为什么我们不能将ddl语句直接写入PL / SQL块


11

为什么我们不能直接在PL / SQL块中编写ddl语句,例如当我编写时

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name; // error
END test;
/

但,

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    execute immediate 'truncate table table_name'; // works fine
END test;
/

为什么第二个成功执行?

Answers:


7

文档中所说:

只有动态SQL才能在PL / SQL程序单元中执行以下类型的语句:

  • 数据定义语言(DDL)语句,例如CREATE,DROP,GRANT和REVOKE

一个TRUNCATE操作是DDL

使用时EXECUTE IMMEDIATE,请记住,DDL您执行的任何操作都将隐式COMMIT当前事务。


1

PL / SQL代码中的DDL比实际需要更多的例外。解析可以看作是结构验证,如果您的结构在执行时发生更改,则会丢失解析。该过程旨在再次解析其他对象(表或其他pl / sql代码,视图等)。每次依赖对象更改时,都应重新编译。因此,无法验证解析代码而不是更改结构,因此无法进行编译。考虑案例

DROP TABLE T1;

在解析期间,将找到表并成功编译过程,但是在第一次执行时,将删除表并且您的代码不再有效(下次DROP TABLE将导致错误)。同样,对表DDL的任何更改都将导致需要重新编译,从而失去了代码解析的优势。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.