あなたは本の他のいくつかの部分を見逃しました。はい、スティーブンは真実です–例外がブロックで発生した場合、先行するすべての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
効果はそのまま残ります。 (そして、そのブロックにはコミットがないため、トランザクションが進行中であることになります。)