Порой случается, что надо чтобы код выполнял запрос, который заранее точно не известен, для решения таких задач в СУБД Oracle существует 3 способа решения данной задачи.
Здесь я только перечислю те решения, которыми мне доводилось пользоваться, подробности можно почерпнуть из документации Oracle.
Здесь я только перечислю те решения, которыми мне доводилось пользоваться, подробности можно почерпнуть из документации Oracle.
- EXECUTE IMMEDIATE
Наиболее часто используемый мной подход. После имени этой команды подаём строку с SQL запросом, которая немедленно выполняется. Для того, чтобы нас не считали неграмотными программистами используем bind переменные, которы позволяют избежать многократного распарсивания запроса. Также из EXECUTE IMMEDIATE можно возвращать данные при помощи INTO и BULK COLLECT INTO.
Подробная документация находится по этой ссылке: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/dynamic.htm#BHCEBBAI - OPEN FOR
Конструкция, которой я пользуюсь очень редко, т.к. обычно хватает способа под цифрой 1. По сути - это курсор, даже не знаю как его правильно назвать, явным или неявный. Дело заключается в том, что для того, чтобы воспользоваться данной командой необходимо создать курсорную переменную типа REF CURSOR. Далее работаем как и с обычными курсорами.
Вот пример:
declare
type t_cursor REF CURSOR;
cursor t_sursor;
num number;
begin
OPEN cursor FOR 'select 1 from dual';
fetch cursor into num;
close cursor;
end; - Пакет DBMS_SQL
Пакет очень мощный, но в тоже время не очевидный, чтобы с ним разобраться рекомендую почитать не только документацию по адресу: http://download.oracle.com/docs/cd/E14072_01/appdev.112/e10577/d_sql.htm , но и сайт на русском языке: http://osql.ru/?p=111
Рекомендую обратить особое внимание на функции TO_CURSOR_NUMBER и TO_REFCURSOR , они помогают конвертировать курсор из обычного формата в DBMS_SQL формат и обратно.
Исправте ошибки в примерах.
ОтветитьУдалитьdeclare
type t_cursor REF CURSOR;
cursor t_sursor;
num number;
begin
OPEN cursor FOR 'select 1 from dual';
fetch cursor into num;
close cursor;
end;
на
declare
type t_cursor IS REF CURSOR;
v_cur t_cursor;
v_num number;
begin
OPEN v_cur FOR 'select 1 from dual';
loop
fetch v_cur into v_num;
exit when v_cur%notfound;
... -- Обработка
end loop;
close v_cur;
end;