【问题标题】:Execute Immediate?立即执行?
【发布时间】:2019-06-21 02:26:16
【问题描述】:

为什么我们在 PL/SQL 中使用execute immediate 命令?

我正在查看以前同事编写的一些程序,我看到该人已经使用execute immediate 很多时间来记录程序的进度以及截断表格时。

我的问题是他为什么要这样做?我们不能像在 pl/sql proc 中那样截断表吗?

【问题讨论】:

  • 你能发布一个使用 EXECUTE IMMEDIATE 来记录消息的例子吗?这听起来很奇怪。 (而预期使用 TRUNCATE:TRUNCATE 是 DDL,我们不能在 PL/SQL 中执行 DDL,除非通过特殊措施)。

标签: oracle plsql dynamic-sql


【解决方案1】:

Oracle 不允许在可执行块中执行 DDL。这是不允许的

begin
    alter table . . . 
end;

最初 Oracle 有 SYS.DBMS_DDL 包来完成这项工作。但是使用起来比较麻烦,所以oracle引入了execute immediate circa v9。

【讨论】:

    【解决方案2】:

    除了从 PL/SQL 执行 DDL(您已经被告知)之外,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>
    

    【讨论】:

    • +1。我很高兴您有时间并愿意给出更广泛的答案。我直接在 OPs DDL 挣扎之后去了。但 IMO 这个问题已经在 Oracle 文档中得到解答。
    • 非常感谢您对此的详细回复(附有更多信息)。
    猜你喜欢
    • 1970-01-01
    • 2019-05-04
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多