在 PL\SQL 块中使用 EXECUTE IMMEDIATE

Posted

技术标签:

【中文标题】在 PL\\SQL 块中使用 EXECUTE IMMEDIATE【英文标题】:Using EXECUTE IMMEDIATE inside PL\SQL Block在 PL\SQL 块中使用 EXECUTE IMMEDIATE 【发布时间】:2014-07-11 07:12:53 【问题描述】:

在 PL\SQL 块中使用 EXECUTE IMMEDIATE 会使整个块立即提交。

begin 

INSERT INTO Customer ( GUID, STATUS, NAME) VALUES (1,1,'xx');

EXECUTE IMMEDIATE 'CREATE TABLE Shop
(
  GUID         NUMBER(16),
  STATUS       NUMBER(1),
  NAME         VARCHAR2(50 BYTE),
)
LOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING';

DBMS_OUTPUT.PUT_LINE('DONE:'); 

EXCEPTION  -- exception handlers begin 
  WHEN OTHERS THEN  -- handles all other errors 
  DBMS_OUTPUT.PUT_LINE('Error occured, rollback...'); 

 ROLLBACK;
end; 

正如您所意识到的,我什至不使用 COMMIT。关于上面的代码,

“Insert into”语句有效,但“create table”语句抛出异常,因为数据库中已经存在同名表。

当我查看数据库时,我没有任何提交语句和代码块出现异常并回滚,我看到插入已经工作并且有一个新行。预计它不应该在那里,因为没有提交并且回滚也有效..

发生异常时如何回滚。

【问题讨论】:

这是因为 DDL 在 Oracle 中不是事务性的。请参阅:Oracle: DDL and transaction rollback。 EXECUTE IMMEDIATE 不会提交,但你的 CREATE TABLE 会。 【参考方案1】:

您可以输入此 PL/SQL 代码:

begin 

EXECUTE IMMEDIATE 'CREATE TABLE Shop
(
     GUID         NUMBER(16),
     STATUS       NUMBER(1),
     NAME         VARCHAR2(50 BYTE),
)
LOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING';
DBMS_OUTPUT.PUT_LINE('DONE:'); 

INSERT INTO Customer ( GUID, STATUS, NAME) VALUES (1,1,'xx');

EXCEPTION  -- exception handlers begin 
    WHEN OTHERS THEN  -- handles all other errors 
    DBMS_OUTPUT.PUT_LINE('Error occured, rollback...'); 

ROLLBACK;
end; 

所以首先它会创建表,如果发生异常它将回滚事务并且插入语句将不起作用。希望这对你有用..

【讨论】:

以上是关于在 PL\SQL 块中使用 EXECUTE IMMEDIATE的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在一个 PL/SQL 块中使用多个函数吗

如何在匿名 PL/SQL 块中自动显示所有 SQL 语句的输出

在 pl/sql 块中使用 OR 运算符匹配行中的值

如何处理 pl/sql 块中的编译时异常?

匿名 pl/sql 块中的声明顺序

为啥在匿名 PL/SQL 块中没有立即引发异常?