ОШИБКА [37000] [IBM] [Драйвер CLI] CLI0118E Неверный синтаксис SQL. SQLSTATE = 37000

У меня есть простой запрос оператора SQL, который выполняется как команда из кода C#. Он нацелен на DB2. Я создал переменные для сервера / схем следующим образом. Выдает ошибку.

private const string DB2Query
            = @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";

Я получаю эту ошибку.

ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000

Однако я не получаю эту ошибку при выполнении из SQL следующим образом:

SELECT Name as Name 
FROM MyServer..FOR3.Application 
WHERE ID = 'MOM'

Чтобы поддержать это, я также попытался сделать что-то вроде ниже в коде, но все равно выдает другую ошибку.

 private const string DB2Query
                    = @"SELECT Name as Name FROM {ServerName}..{Schema}.Application WHERE ID = ?";

Это вызывает ошибку в этой строке кода:

DataApplicationBlockHelper<string>.Get(db, dbCommand, Obj);

ОБНОВИТЬ

Я нашел виноватого. Он не заменяет заполнитель {Schema}. Когда я действительно удалил это из запроса и поместил имя схемы, это сработало как шарм. Я верю, что это домен .net? Может кто-нибудь помочь, как заменить {Schema} значением, полученным из web.config?

Если это для IBM DB2 - зачем вы добавили к этому тег sql-server?!?!?

marc_s 14.01.2019 06:08

@marc_s: Некоторые люди вроде вас могут быть экспертами во всем :) Или, по крайней мере, столкнулись бы с подобными, например, я народ MS, и теперь мне пришлось работать с D2 :( Вот почему я добавил, чтобы намекнуть этим ребятам если они в курсе :)

Jasmine 14.01.2019 06:14

@marc_s: Вы помогли мне в прошлый раз, и ТОЛЬКО вы во всем мире отметили ту точку версии SQL Server, где 2005 не поддерживает конструктор с табличной оценкой, и моя групповая вставка не удалась, а отдельная вставка прошла. Никто не мог об этом подумать, и все винили только меня. Только вы запросили версию и совместимость, и я сравнил свой личный ноутбук, где он работал, и мой офис, он не работал, и когда я публикую разницу в версиях, некоторые люди сказали, что он не поддерживается. Anywya это не связано с этим вопросом :)

Jasmine 14.01.2019 06:19

@marc_s: Я нашел виноват. Это не заменяет {схему}. Когда я действительно удалил это из запроса и поместил имя Scnema, это сработало как шарм. Я верю, что это .net вещь? Не могли бы вы помочь, как заменить "{Schema}" на другое значение, полученное из web.config?

Jasmine 14.01.2019 06:31

Я ничего не знаю о DB2, но я считаю, что вся концепция "схемы" вполне соответствует конкретный для SQL Server, поэтому я не думаю, что вы можете просто "заменить" заполнитель schema чем-то из web.config и запустить это в DB2 - вы скорее всего, вам просто нужны операторы SQL разные для DB2, чем вы можете использовать для SQL Server.

marc_s 14.01.2019 06:42

@marc_s: Почему моя функция Replace не заменяет его? Я делаю это в конструкторе. Когда я смотрю на запрос, он все еще говорит {Schema}, и я не вижу веской причины. Его путь до того, как мы коснемся DB2. Правильно? Возможно, я ошибаюсь, но интересно знать. Я новичок в программировании. Кроме того, я подозреваю, что используется постоянное значение, начинающееся с escape ignore "@"?

Jasmine 14.01.2019 06:45

@marc_s: Мне любопытно, что простая замена строки не заменяет. Почему?

Jasmine 14.01.2019 06:47

Даже если вы замените {schema} пустой строкой, у вас все равно будет точка . между {schema} и Application в вашем SQL-запросе, которой для DB2, вероятно, не должно быть.

marc_s 14.01.2019 06:47

@marc_s: Нет, это имя схемы. this.noSql = noSqlDefinition.Replace ("{Схема}", this.DBSchema);

Jasmine 14.01.2019 06:48

Это то, что я делаю. Но он не заменяет {Schema} моим именем схемы, которое я получил из web.config. Я делаю это в конструкторе

Jasmine 14.01.2019 06:48

Хорошо, но, как я уже сказал: скорее всего, DB2 не знать о схеме ....... это специфично для SQL Server. Ö ...

marc_s 14.01.2019 06:48

@marc_s: Нет, в визуализаторе DB2 отлично работает. Фактически, все мои коды используют этот формат. Не знаю, что случилось. Когда я заменяю правильное имя схемы вместо {Schema}, все работает отлично. Что-то не так в замене, как я видел в одном блоге github.com/lionheart/django-pyodbc/issues/123

Jasmine 14.01.2019 06:52

если вы используете C# 6, вы можете использовать знак $ вместо знака @ в строках (что заставит вашу текущую строку работать). см. docs.microsoft.com/en-us/dotnet/csharp/language-reference/…

iSR5 14.01.2019 07:00

@ iSR5: lol, откуда мне знать, что я использую C# 6?

Jasmine 14.01.2019 13:40

@Learner, если вы используете .NET 4.6, значит, вы используете C# 6. Вам также необходимо использовать VS 2015 или выше, чтобы получить полную поддержку.

iSR5 14.01.2019 14:02

@Learner хорошее объяснение здесь stackoverflow.com/questions/19532942/…

iSR5 14.01.2019 14:03
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
16
495
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хотя я не могу говорить о синтаксисе самих запросов DB2, поэтому я буду полагаться на ваше утверждение, что запрос сам должен работать ...

То, что у вас есть в C#, - это просто строка и не более:

private const string DB2Query = @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";

Обратите внимание, что в этом определении строки нет необходимости в операторе @, поэтому давайте упростим:

private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";

Хотя эта строка выглядит как интуитивно, чтобы иметь заполнитель, который можно заменить значением, если нет кода, который делает это где-либо, этого не произойдет. Для этого у вас есть несколько вариантов. Например, вы можете использовать заполнитель, который понимает string.Format():

private const string DB2Query = "SELECT Name as Name FROM {0}.Application WHERE ID = ?";

А затем позже в каком-нибудь методе, когда вы захотите использовать эту строку, примените к ней значение формата:

var sql = string.Format(DB2Query, someVariable);

В этом случае someVariable (который даже не обязательно должен быть переменной и может быть строковым литералом) будет использоваться для замены заполнителя в строке.


Или, если вы хотите сохранить именованный заполнитель, вы можете заменить его вручную:

private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";

и позже в методе:

var sql = DB2Query.Replace("{Schema}", someVariable);

Очевидно, это приведет к тому же результату, возможно, с очень незначительной разницей в производительности.


Вы также можете воспользоваться преимуществами обоих подходов, используя новейшую языковую функцию интерполяции строк. Это будет использовать оператор $ для непосредственного применения заполнителей формата на месте. Я не думаю, что вы можете использовать это в const, это больше для локальной переменной. Что-то вроде этого:

var sql = $"SELECT Name as Name FROM {someVariable}.Application WHERE ID = ?";

Это все равно выполнит ту же замену, поместив someVariable на место заполнителя, просто используется более сжатый синтаксис, чем при вызове string.Format(). Об этом синтаксисе следует отметить то, что он делает его более похожим на то, что эта интерполяция происходит непосредственно на месте в строке. Это все еще многоступенчатый процесс за кулисами, поэтому он, скорее всего, не будет работать на const или на членах класса вообще (и должен ли я представить ошибку компилятора).

Помните, что строки - это неизменный, поэтому любая операция, которую вы выполняете, которая изменяет является строкой, будет возвращать строку новый, а не изменять существующую на месте.


В любом случае вам, конечно, также необходимо применить параметр запроса для заполнителя ?. Обратите внимание, что то, что C# считает заполнителем в операции форматирования / интерполяции строки, и то, что DB2 считает заполнителем для параметра запроса, - это две совершенно разные вещи, которые происходят в разное время в разных средах. (Один в среде выполнения .NET, один в выполнении запроса сервера базы данных.) Но опять же, я полагаюсь на ваше утверждение, что сам запрос к базе данных работает, и единственная проблема, на которой мы здесь сосредоточены, - это заполнитель строки C#.

Дэвид, большое спасибо за подробный ответ. Запрос работает отлично. Теперь я уже использовал ваш второй подход с использованием функции замены. В моем проекте старые коды, и в них уже есть тот же код, что и вы написали. Однако это не работает (возможно, это может сработать для среды prod?), Потому что они настроили среду DB как Prod для этих переменных. Теперь, для подключений Dev DB2, возможно, это может не работать из-за различных настроек конфигурации, возможно, в DB2 for Dev и Prod? Я не знаю.

Jasmine 14.01.2019 13:48

Что ж, я смогу попробовать ваш первый подход только завтра утром, как только приду в офис. Сейчас 11.48 вечера :) Большое спасибо, это очень проницательно. И настраивайтесь, чтобы получить от меня ответ;)

Jasmine 14.01.2019 13:48

@ Ученик: «Я уже использовал ваш второй подход с функцией замены» - А это как-то не сработало? Если нет, вы захотите указать в вопросе, что вы пробовали и как это работает не так, как ожидалось. "возможно, это может не сработать из-за различных настроек конфигурации, возможно, в DB2 for Dev и Prod?" - Определить «может не сработать», что конкретно не получается? Если что-то в DB2 выходит из строя, то это выходит за рамки вашего заданного вопроса, поскольку ваш вопрос утверждает, что запрос DB2 работает должным образом. Если вы спрашиваете о форматировании строк C#, это не имеет ничего общего с DB2.

David 14.01.2019 14:03

Я понимаю, что я разместил два оператора Replace, один из которых является схемой, а другой - сервером, хотя на самом деле я не указал какой-либо сервер в запросе, поскольку я удалил заполнитель сервера из запроса, но не забыл удалить заменяющий. для этого. Но какого черта это вызовет ошибку? Я бы предположил, ТОЛЬКО если есть какая-то строка, которую нужно заменить, найдите ее и, если да, замените, иначе игнорируйте и уходите. Какого черта он выбрасывает несущественные ошибки. Черт, потратил полдня впустую

Jasmine 14.01.2019 14:24

Я удалился в свой офис, хотя сейчас 12.20. Во всяком случае, его разобрали. Я могу спать спокойно. Большое вам спасибо за вашу помощь.

Jasmine 14.01.2019 14:24

Другие вопросы по теме