Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
Экранирование ' для
imidiate execute Есть огромный статический по тексту запрос, который пытаюсь сделать динамическим Часть колонок в нем меняются ( разные имена и число) в зависимости от некого справочника Застрял с глупостью В исходном не динамическом запросе есть куски типа '{'||substr()||'}' case when a= 'bbb' then 'ccc' else 'ddd' Заменил подставляемые вещи переменными до запроса var:= '{' ; var1:='}'; var2 :='||' ; А в запросе подставляю их параметрами :var||substr ... Получается верно только при использовании using в противном случает строка для запроса формируется неверно типа case a :={ then bbb ( без кавычек Как же туда в строку формируемого запроса засунуть исходный вариант '{'||substr()||'}' С using выходит верно, но число мест замены очень большое, постоянно путаюсь с правильным местом этого самого using Очень хочется без него без потери одиночный апострофов и '||' |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
При генерации текстов запросов надо просто удвоить кавычку.
------------------ WBR, Igor |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
select case
when f10022 != ' ' then '{' || substr(f10022, 1, 6) || '}' || substr(f10022, 7) else ' ' end as f10022, case when f10023 != ' ' then '{' || substr(f10023, 1, 6) || '}' || substr(f10023, 7) else ' ' end as f10023, ___________________ select case when ss.nminref = '_КОНСОЛИДАЦИЯ' then ' ' else aa.nminref end as f10022, case when ss.nminref = '_КОНСОЛИДАЦИЯ' then ' ' else bb.nminref end as f10023, __________________________ case when ss.nminref = '_КОНСОЛИДАЦИЯ' then '_КОНСОЛИДАЦИЯ' else 'Не Консолидация' end as f6004, ___________________________ case when nvl(t.value, '0') = 0 then tt.nminref else '_КОНСОЛИДАЦИЯ' end as nminref, Пытаюсь заменить так lcbl := ' '; lbl := '{'; lbr := '}'; lnvl :='0'; lccons := '_КОНСОЛИДАЦИЯ'; nodef := 'NULL НЕ ОПРЕДЕЛЕНО'; lcncons := 'Не Консолидация'; l_query := 'select case when f10022 != :lcbl'; l_query := l_query || ' then :lbl '|| '|| substr(f10022, 1, 6) ||:lbr '|| '|| substr(f10022, 7) else :lcbl ' || ' end as f10022,'; l_query := l_query || ' case when f10023 != :lcbl' || ' then :lbl '|| '|| substr(f10023, 1, 6) :lbr ' || ' || substr(f10023, 7) '; l_query := l_query || ' else :lcbl '; l_query := l_query || ' end as f10023,'; |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Если ты хочешь использовать именно параметры, то естественно в динамический запрос они передаются через USING и никак иначе.
Если ты просто хочешь генерировать текст запроса, то нужно именно конкатенацией собирать строки, а не использовать :param и в этом случае для вставки в строку кавычки её нужно удвоить. пример со связываемой переменной.
P.S. связываемые переменные можно использовать ровно в тех же самых "контекстах" как и при посылке обычных запросов. Т.е. к примеру так можно
------------------ WBR, Igor Исправлено 1 раз(а). Последнее : Igor Korolyov, 07.03.19 22:45 |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
Да, Игорь
Фактически подходит только вариант с using так как процедура также имеет in параметры, которые тоже нужно отдать в динамический текст запроса, сделанный из статического Второй день бьюсь с ошибкой- не все переменные привязаны. В тексте ошибки ссылается на первую строчку в запросе, а строчек полторы сотни. То есть ошибка не в первой строке. Число параметров -верное. Беру уже текст , который сгенерился, правлю и запускаю. Черт знает, где ошибка. Сижу режу на мелкие кусочки ,проверяю каждый Это довольно странно, так как сам исходный статичский текст работает исправно уже года два, и естественно тоже писался и отлаживался мелкими кусочками. |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
В общем такое дело
После вызова execute immediate поставил exception с номером ошибки и текстом сформированного запроса. Беру это самый запрос в новое окно, правлю там разорванные на разные строки слова и запускаю. Никакой ошибки, запрос дает результат. Сегодня наконец увидел, что строка , в которой коплю текст запроса, объявленная как varchar максимальной длительности на некой строке склейки меняет тип на long До этой строки был виден в переменной ее текст, а после нее -long Если сократить запрос до этого места, он выполняется через вызова execute immediate Как только переменная буфера запроса меняет тип, запрос валится. Причем ошибка -несовместимость типов. Если оставить в запросе параметры, то ошибка другая- не все переменные привязаны. Но опять таки текст запроса, выведенный в анализе ошибки при переносе в новое окно запроса с редактированием разорванных на разные строки переменные выполняется без ошибки Тексты рвутся потому как вывожу строчками по 150 символов текст запроса. Не совсем понимаю, что с эти теперь делать. |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
pasha_usue Сообщений: 3649 Откуда: Е-бург Дата регистрации: 06.10.2006 |
Где-то конкатенатор перепутан? Вместо || используется +?
Исправлено 1 раз(а). Последнее : pasha_usue, 12.03.19 20:22 |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
1) Менять подход. Текст запроса не помещающийся в 32К символов - это нонсенс.
2) Ты не указываешь используемую версию - в старых версиях execute immediate принимал только типы char/varchar2 - и в принципе не мог исполнять скрипты длиннее 32К символов. В более менее современных он принимает ещё и CLOB - НО с CLOB работают чуть по иному нежели с varchar2. С LONG, насколько я в курсе, не работает ни одна версия. И автоматом тип переменной (где накапливается текст запроса) оракл не меняет - не может varchar2 превратится в long. Вообще раньше для особо больших скриптов рекомендовался пакет DBMS_SQL - там скрипт "построчно" в массив помещался. Но ещё раз советую обратить внимание на п.1 и что-то "поменять в консерватории". Есть масса самых разных способов обработать данные - включая табличные функции. Мега-запросы на 50 страниц текста это уродство хоть в статическом, хоть в динамическом видах. ------------------ WBR, Igor |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
Игорь
Ситуация довольно странная Оракл 11 Длина строки, даже двух строк , которые я клею для динамического запроса всего около 22 строки по 150 символов к моменту вызова execute imidiate Ломается тип где-то посередине формирования второй длинной переменной. Вот этого я в упор не пойму, что это за хрень такая. Строка, где все ломается, довольно банальная, ничем не отличается от строк выше и ниже. Есть другие чужие процедуры,которые клеят строки для помещение в лонг поле, не для запроса , где никакой такой смены типа не происходит. Способов решить задачу действительно несколько. Это самое изменение содержания справочников, которое требует замены текста происходит довольно редко. Я спокойно менял свои статические процедуры в этом случае по звонку буха, который этим занимается. Просто хочется сделать вариант независимый от программиста. Вчера сделал работающую вещь, но она диковата. Считал на фокс текст статической процедуры ( это не трудно, только склеить потом строки и добавить create or replace), запросил справочник, изменил изменил программно в тексте 2 места, требующих нового списка из справочника, снова послал из фокса этот текст назад на Оракл. Все, получилась новая статическая процедура. Только нехорошо рядовому пользователю давать такой доступ. А так даже можно приклеить какой никакой интерфейс. |
Re: Экранирование апострофа Оракл динамический запрос | |
---|---|
boba Автор Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
Прошу прощения за потерянное время и некую
дезинформацию Несоответствие типов оказалось вовсе из другой песни Вместо комментированного -- execute immediate (l_query) -- into p_cursor ; пишу open p_cursor for l_query; и все работает. Варианты с execute imidiate брал из готовых примеров, которые мы работали. Причем, p_cursor объявлен как refcursor |
© 2000-2024 Fox Club  |