Выполнить немедленно? - PullRequest
0 голосов
/ 21 июня 2019

Почему мы используем команду execute immediate в PL / SQL?

Я смотрю на некоторые процедуры, написанные предыдущим коллегой, и вижу, что этот человек много раз использовал execute immediateрегистрировать ход выполнения процедуры, а также при усечении таблиц.

Мой вопрос: зачем ему это делать?Разве мы не можем просто усекать таблицы просто так в pl / sql proc?

Ответы [ 2 ]

4 голосов
/ 21 июня 2019

Oracle не разрешит выполнение DDL внутри исполняемого блока.Это не разрешено

begin
    alter table . . . 
end;

Изначально Oracle имел пакет SYS.DBMS_DDL для этой работы.Но это было громоздко в использовании, поэтому оракул представил execute immediate около v9.

1 голос
/ 21 июня 2019

Помимо выполнения DDL из PL / SQL (о чем вам уже говорили), execute immediate используется для запуска динамического SQL .Что бы это было?Создание операторов, которые зависят от информации, которая неизвестна на момент создания процедуры PL / SQL.Например, выбирая из нескольких таблиц в вашей схеме:

SQL> set serveroutput on
SQL> declare
  2    l_str varchar2(1000);
  3    l_cnt number;
  4  begin
  5    for cur_r in (select table_name from user_tables
  6                  where table_name in ('EMP', 'DEPT', 'BONUS')
  7                 )
  8    loop
  9      l_str := 'select count(*) from ' || cur_r.table_name;
 10      execute immediate l_str into l_cnt;
 11      dbms_output.put_line(cur_r.table_name ||': '|| l_cnt);
 12    end loop;
 13  end;
 14  /
BONUS: 0
DEPT: 4
EMP: 14

PL/SQL procedure successfully completed.

SQL>

Аналогично, вы можете создать функцию, которая использует имена таблиц (или столбцов) динамически , например,

SQL> create or replace function f_cnt (par_table_name in varchar2)
  2    return number
  3  is
  4    l_str varchar2(1000);
  5    l_cnt number;
  6  begin
  7    l_str := 'select count(*) from ' || dbms_assert.sql_object_name(par_table_name);
  8    execute immediate l_str into l_cnt;
  9    return l_cnt;
 10  end;
 11  /

Function created.

SQL> select f_cnt('emp') from dual;

F_CNT('EMP')
------------
          14

SQL>
...