Oracle Database
Динамический SQL
Поиск…
Вступление
Dynamic SQL позволяет собирать код SQL-запроса во время выполнения. Этот метод имеет некоторые недостатки и должен использоваться очень осторожно. В то же время он позволяет реализовать более сложную логику. PL / SQL требует, чтобы все объекты, используемые в коде, должны существовать и быть действительными во время компиляции. Вот почему вы не можете напрямую выполнять инструкции DDL в PL / SQL, но динамический SQL позволяет это сделать.
замечания
Некоторые важные замечания:
Никогда не используйте конкатенацию строк для добавления значений к запросу, вместо этого используйте параметры. Это не верно:
execute immediate 'select value from my_table where id = ' || id_valiable into result_variable;
И это правильно:
execute immediate 'select value from my_table where id = :P ' using id_valiable into result_variable;
Для этого есть две причины. Первая - это безопасность. Конкатенация строк позволяет сделать SQL-инъекцию. В запросе ниже, если переменная будет содержать значение
1 or 1 = 1
, операторUPDATE
обновит все строки в таблице:execute immediate 'update my_table set value = ''I have bad news for you'' where id = ' || id;
Вторая причина - производительность. Oracle будет анализировать запрос без параметров каждый раз, когда он выполняется, тогда как запрос с параметром будет анализироваться только один раз в сеансе.
Обратите внимание, что когда механизм базы данных выполняет оператор DDL, он выполняет неявное совершение ранее.
Выберите значение с динамическим SQL
Предположим, пользователь хочет выбрать данные из разных таблиц. Пользователь задает таблицу.
function get_value(p_table_name varchar2, p_id number) return varchar2 is
value varchar2(100);
begin
execute immediate 'select column_value from ' || p_table_name ||
' where id = :P' into value using p_id;
return value;
end;
Вызовите эту функцию как обычно:
declare
table_name varchar2(30) := 'my_table';
id number := 1;
begin
dbms_output.put_line(get_value(table_name, id));
end;
Таблица для тестирования:
create table my_table (id number, column_value varchar2(100));
insert into my_table values (1, 'Hello, world!');
Вставка значений в динамический SQL
Пример ниже вставляет значение в таблицу из предыдущего примера:
declare
query_text varchar2(1000) := 'insert into my_table(id, column_value) values (:P_ID, :P_VAL)';
id number := 2;
value varchar2(100) := 'Bonjour!';
begin
execute immediate query_text using id, value;
end;
/
Обновить значения в динамическом SQL
Давайте обновим таблицу из первого примера:
declare
query_text varchar2(1000) := 'update my_table set column_value = :P_VAL where id = :P_ID';
id number := 2;
value varchar2(100) := 'Bonjour le monde!';
begin
execute immediate query_text using value, id;
end;
/
Выполнить инструкцию DDL
Этот код создает таблицу:
begin
execute immediate 'create table my_table (id number, column_value varchar2(100))';
end;
/
Выполнять анонимный блок
Вы можете выполнить анонимный блок. В этом примере также показано, как вернуть значение из динамического SQL:
declare
query_text varchar2(1000) := 'begin :P_OUT := cos(:P_IN); end;';
in_value number := 0;
out_value number;
begin
execute immediate query_text using out out_value, in in_value;
dbms_output.put_line('Result of anonymous block: ' || to_char(out_value));
end;
/