Поиск…


Вступление

Dynamic SQL позволяет собирать код SQL-запроса во время выполнения. Этот метод имеет некоторые недостатки и должен использоваться очень осторожно. В то же время он позволяет реализовать более сложную логику. PL / SQL требует, чтобы все объекты, используемые в коде, должны существовать и быть действительными во время компиляции. Вот почему вы не можете напрямую выполнять инструкции DDL в PL / SQL, но динамический SQL позволяет это сделать.

замечания

Некоторые важные замечания:

  1. Никогда не используйте конкатенацию строк для добавления значений к запросу, вместо этого используйте параметры. Это не верно:

    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 будет анализировать запрос без параметров каждый раз, когда он выполняется, тогда как запрос с параметром будет анализироваться только один раз в сеансе.

  2. Обратите внимание, что когда механизм базы данных выполняет оператор 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;
/


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow