これは興味深い質問です!
Oracleでエラーが発生すると、現在のステートメントがロールバックされます。 、トランザクションではありません。ステートメントは任意の最上位命令であり、SQLステートメント(INSERT、UPDATE ...)またはPL/SQLブロックにすることができます。
これは、ステートメント(たとえば、javaから呼び出されたpl / sqlプロシージャ)がエラーを返す場合、Oracleはトランザクションを呼び出し前と同じ論理状態にすることを意味します。これは非常に役立ちます。半分実行された手順について心配する必要はありません(**)。
AskTomのこのスレッドは、同じトピックをカバーしています:
[ステートメント]完全に発生するか、完全に発生しないかのいずれかであり、機能する方法は、データベースが次の論理的等価物を実行することです。
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
私の意見では、この機能が、他のどの言語よりもpl / sqlでデータベースコード(*)を作成する方がはるかに簡単である理由です。
(*)もちろん、Oracle DBと相互作用するコードですが、他のDBMSのネイティブ手続き型言語にも同様の機能があると思います。
(**)DDLはOracleではトランザクションではないため、これはDMLにのみ関係します。データディクショナリを更新する一部のDBMSパッケージ(DBMS_STATS
など)にも注意してください。 )、彼らはしばしばDDLのような変更を行い、コミットを発行します。疑問がある場合は、ドキュメントを参照してください。
更新: この動作はPL/SQLの最も重要な概念の1つです。pl/sqlステートメントの原子性を示すための小さな例を示します。 :
SQL> CREATE TABLE T (a NUMBER);
Table created
SQL> CREATE OR REPLACE PROCEDURE p1 AS
2 BEGIN
3 -- this statement is successful
4 INSERT INTO t VALUES (2);
5 -- this statement will raise an error
6 raise_application_error(-20001, 'foo');
7 END p1;
8 /
Procedure created
SQL> INSERT INTO t VALUES (1);
1 row inserted
SQL> EXEC p1;
begin p1; end;
ORA-20001: foo
ORA-06512: at "VNZ.P1", line 5
ORA-06512: at line 2
SQL> SELECT * FROM t;
A
----------
1
Oracleは、トランザクションをp1を呼び出す直前のポイントにロールバックしました。中途半端な作業はありません。プロシージャp1が呼び出されたことがないかのようです。