Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DML和异常处理-Oracle_Oracle - Fatal编程技术网

DML和异常处理-Oracle

DML和异常处理-Oracle,oracle,Oracle,根据Steven Feuerstein的书 当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(

根据Steven Feuerstein的书

当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;

但我的表仍然包含这两行。我错过了什么?

你错过了这本书的其他部分。是的,史蒂文是正确的-如果一个块中发生异常,所有前面的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;

,则您的
删除
效果将保持不变。(由于该块中没有提交,因此您最终会有一个正在进行的事务。)

未提交的事务?您使用的是什么客户端?也许它会在异常后回滚?作为@Stawros sadid,您忘记了委员会关于事务和游标行为的一些基本原则的优秀问题。谢谢您的帮助,我的概念现在已经清楚了:)