根据的书
当PL/SQL块中出现异常时,Oracle数据库不会回滚DML语句在该块中所做的任何更改。您是应用程序逻辑事务的管理器,因此您决定应该发生什么样的行为。
我试试看:
CREATE TABLE DML_Exception (exception_name VARCHAR2(20));
INSERT INTO DML_exception VALUES('CASE_NOT_FOUND');
INSERT INTO DML_exception VALUES('TOO_MANY_ROWS');我的桌子上有两排
Select * from DML_Exception现在,我从表中删除了两行,并在PL/SQL块中引发异常。
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;但我的表仍然包含这两行。我错过了什么?
发布于 2015-11-05 10:23:01
你错过了书的其他部分。是的,Steven是真的--如果在块中发生异常,那么前面所有的DML效果都将保持不变。然而,书中还应该提到,任何顶级SQL或PL/SQL语句(也就是匿名块)执行都会为该语句打开一个游标,如果在游标执行过程中出现异常,那么游标执行期间所做的所有DML效果都会被回滚。也许一个简单的例子会给你线索..。
在你最初的例子中,你执行了..。
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;..。作为最高级别的声明。是的,在块的末尾,虽然还在,但您的delete效果仍然存在。然而,您的块引发了一个异常,该异常一直传播到顶层游标。因此,为了遵守原子性的原则,Oracle回滚了打开游标的所有挂起的效果。
如果从另一个顶级PL/SQL块中调用PL/SQL块,该块处理而不重新引发在较低级别PL/SQL块中引发的异常,.
BEGIN
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
EXCEPTION
WHEN others THEN NULL;
END;.那么你的delete效应就会继续存在。(而且,由于该块中没有提交,所以您最终会得到一个正在进行的事务。)
https://stackoverflow.com/questions/33540754
复制相似问题