автоматически сгенерированный SQL-код: одиночная обратная косая черта в качестве escape-символа - PullRequest
4 голосов
/ 02 сентября 2010

Я запрашиваю базу данных oracle 9i с помощью:

SELECT * FROM таблицы, ГДЕ столбец LIKE '%' || ‘SomeText’ || '%' ESCAPE '\';

и происходит сбой с ошибкой «escape-символ должен быть символьной строкой длины 1» (ошибка ORA-01425) при успешном выполнении в базе данных Oracle Express 10g.

Создание двойной обратной косой черты (ESCAPE '\\') решает проблему для базы данных oracle 9i, но вместо этого генерирует ту же ошибку ORA-01425 для базы данных 10g.

Я не могу редактировать SQL, поскольку он автоматически генерируется с помощью Telerik OpenAccess ORM.

Код Linq, который приводит к приведенному выше SQL:

activity.Name.Contains. ( "SOMETEXT")

Мне бы хотелось, чтобы обе базы данных обрабатывали ESCAPE '\' ... Или вместо этого, был бы другой способ поиска элементов таблицы по их имени или описанию.

Заранее спасибо!

Ответы [ 5 ]

2 голосов
/ 16 сентября 2010

Не знаком с Linq, но меня немного смущает вопрос о том, где вы выполняете запрос - просто вставляете сгенерированный код в SQL * Plus, работающий с двумя базами данных, где это поведение можно хотя бы объяснить?

Если вы делаете это в SQL * Plus, выполните show escape в каждой среде;Я подозреваю, что 9i сообщит escape "\" (hex 5c), в то время как 10g сообщит escape off.Это может указывать на то, что обработка экранирования ранее была настроена в экземпляре 9i, но не в (предположительно более позднем) 10g.

Если что-то из этого оказалось актуальным, попробуйте выполнить set escape \ в сеансе 10g и попробуйте версию \\ снова.А в 9i попробуйте сделать escape off и попробуйте там версию \.Теперь оба должны работать.

Предполагая, что вы все еще со мной, следующий вопрос заключается в том, почему 9i имеет такую ​​настройку;вероятно, есть файл login.sql или glogin.sql, который устанавливает его автоматически.Вы можете удалить это, если это не повлияет на что-либо еще, чтобы сгенерированный код мог работать без изменений.

Не думаю, что что-то из этого будет уместно, если высобираюсь выполнить код другим способом;не уверен, что вы просто тестируете и отлаживаете сгенерированный код в SQL * Plus и, в конце концов, будете выполнять его в другом месте (опять же, без знания Linq), в этом случае это может быть временной проблемой в любом случае.

IЯ также не уверен, что вы на самом деле избегаете ...

1 голос
/ 22 октября 2010

На случай, если кто-нибудь зайдет с той же проблемой ... Моя проблема заключалась в том, что я имел дело с полями «NVARCHAR2». Я получил помощь по этому вопросу на форумах оракула:)

Этот запрос: выберите * из двойного, где 'пустышка', как '%' escape '\';

работает в обоих случаях, потому что поле "dummy" - varchar2. Если бы это был nvarchar2, то часть запроса, которая могла бы (только возможно!) Вызвать проблемы, была бы частью «escape» \ (»мой оракул 9i хочет escape« \ », мой оракул 10g хочет« \\ »).

Чтобы решить эту проблему, вместо использования автоматически сгенерированного кода ORM я написал хранимую процедуру (только при поиске строк), в которой я обрабатываю поля nvarchar2, например: где TableName.ColumnName, например, N '%' || ‘SomeText’ || N '%' escape N '\'

И работает нормально :) 1009 *

Это, однако, не объясняет, как, имея одинаковые столбцы NVARCHAR2 и одинаковые запросы SQL, они обрабатывались двумя серверами оракула по-разному (10g express на моем локальном ПК и 9i) - это остается вопросом , Поэтому для тех, кто сталкивается с подобными проблемами, было бы полезно узнать, является ли это проблемой nvarchar2 (я понятия не имел, что это может быть проблемой), и попытаться обойти ее.

1 голос
/ 16 сентября 2010

Сбой для каждого ввода или только для определенных строк? Проблема может быть не в запросе, а во вводе. Если существует нечетное количество обратных слешей, Oracle может попытаться избежать чего-то, что не должно быть спасением.

Например, это работает, потому что экранирует '%':

select * from dual  where 'test' like '%'||'\'||'%' escape '\';

Но это не удается, потому что он пытается избежать «а», который не нуждается в экранировании:

select * from dual  where 'test' like '%'||'\a'||'%' escape '\';

Можете ли вы изменить строку до ее передачи в функцию и исправить странные обратные слэши?

1 голос
/ 04 сентября 2010

вы могли бы избежать проблемы с обратной косой чертой. Попробуйте вместо этого использовать фигурные скобки вокруг экранированных символов.

http://download.oracle.com/docs/cd/B10500_01/text.920/a96518/cqspcl.htm

1 голос
/ 02 сентября 2010

Попробуйте:

  SELECT * FROM TABLENAME 
  WHERE COLUMNNAME LIKE '\%' ESCAPE '\';

Обычно символ ESCAPE в LIKE используется для разрешенных символов поиска "%" и "_"

...