У меня есть простой запрос оператора 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?
@marc_s: Некоторые люди вроде вас могут быть экспертами во всем :) Или, по крайней мере, столкнулись бы с подобными, например, я народ MS, и теперь мне пришлось работать с D2 :( Вот почему я добавил, чтобы намекнуть этим ребятам если они в курсе :)
@marc_s: Вы помогли мне в прошлый раз, и ТОЛЬКО вы во всем мире отметили ту точку версии SQL Server, где 2005 не поддерживает конструктор с табличной оценкой, и моя групповая вставка не удалась, а отдельная вставка прошла. Никто не мог об этом подумать, и все винили только меня. Только вы запросили версию и совместимость, и я сравнил свой личный ноутбук, где он работал, и мой офис, он не работал, и когда я публикую разницу в версиях, некоторые люди сказали, что он не поддерживается. Anywya это не связано с этим вопросом :)
@marc_s: Я нашел виноват. Это не заменяет {схему}. Когда я действительно удалил это из запроса и поместил имя Scnema, это сработало как шарм. Я верю, что это .net вещь? Не могли бы вы помочь, как заменить "{Schema}" на другое значение, полученное из web.config?
Я ничего не знаю о DB2, но я считаю, что вся концепция "схемы" вполне соответствует конкретный для SQL Server, поэтому я не думаю, что вы можете просто "заменить" заполнитель schema чем-то из web.config и запустить это в DB2 - вы скорее всего, вам просто нужны операторы SQL разные для DB2, чем вы можете использовать для SQL Server.
@marc_s: Почему моя функция Replace не заменяет его? Я делаю это в конструкторе. Когда я смотрю на запрос, он все еще говорит {Schema}, и я не вижу веской причины. Его путь до того, как мы коснемся DB2. Правильно? Возможно, я ошибаюсь, но интересно знать. Я новичок в программировании. Кроме того, я подозреваю, что используется постоянное значение, начинающееся с escape ignore "@"?
@marc_s: Мне любопытно, что простая замена строки не заменяет. Почему?
Даже если вы замените {schema} пустой строкой, у вас все равно будет точка . между {schema} и Application в вашем SQL-запросе, которой для DB2, вероятно, не должно быть.
@marc_s: Нет, это имя схемы. this.noSql = noSqlDefinition.Replace ("{Схема}", this.DBSchema);
Это то, что я делаю. Но он не заменяет {Schema} моим именем схемы, которое я получил из web.config. Я делаю это в конструкторе
Хорошо, но, как я уже сказал: скорее всего, DB2 не знать о схеме ....... это специфично для SQL Server. Ö ...
@marc_s: Нет, в визуализаторе DB2 отлично работает. Фактически, все мои коды используют этот формат. Не знаю, что случилось. Когда я заменяю правильное имя схемы вместо {Schema}, все работает отлично. Что-то не так в замене, как я видел в одном блоге github.com/lionheart/django-pyodbc/issues/123
если вы используете C# 6, вы можете использовать знак $ вместо знака @ в строках (что заставит вашу текущую строку работать). см. docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
@ iSR5: lol, откуда мне знать, что я использую C# 6?
@Learner, если вы используете .NET 4.6, значит, вы используете C# 6. Вам также необходимо использовать VS 2015 или выше, чтобы получить полную поддержку.
@Learner хорошее объяснение здесь stackoverflow.com/questions/19532942/…


Хотя я не могу говорить о синтаксисе самих запросов 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? Я не знаю.
Что ж, я смогу попробовать ваш первый подход только завтра утром, как только приду в офис. Сейчас 11.48 вечера :) Большое спасибо, это очень проницательно. И настраивайтесь, чтобы получить от меня ответ;)
@ Ученик: «Я уже использовал ваш второй подход с функцией замены» - А это как-то не сработало? Если нет, вы захотите указать в вопросе, что вы пробовали и как это работает не так, как ожидалось. "возможно, это может не сработать из-за различных настроек конфигурации, возможно, в DB2 for Dev и Prod?" - Определить «может не сработать», что конкретно не получается? Если что-то в DB2 выходит из строя, то это выходит за рамки вашего заданного вопроса, поскольку ваш вопрос утверждает, что запрос DB2 работает должным образом. Если вы спрашиваете о форматировании строк C#, это не имеет ничего общего с DB2.
Я понимаю, что я разместил два оператора Replace, один из которых является схемой, а другой - сервером, хотя на самом деле я не указал какой-либо сервер в запросе, поскольку я удалил заполнитель сервера из запроса, но не забыл удалить заменяющий. для этого. Но какого черта это вызовет ошибку? Я бы предположил, ТОЛЬКО если есть какая-то строка, которую нужно заменить, найдите ее и, если да, замените, иначе игнорируйте и уходите. Какого черта он выбрасывает несущественные ошибки. Черт, потратил полдня впустую
Я удалился в свой офис, хотя сейчас 12.20. Во всяком случае, его разобрали. Я могу спать спокойно. Большое вам спасибо за вашу помощь.
Если это для IBM
DB2- зачем вы добавили к этому тегsql-server?!?!?