web-dev-qa-db-ja.com

Oracleストアドプロシージャでのコミットとロールバック

私のOracleストアドプロシージャには、次のような複数の挿入および更新ステートメントがあります。

create or replace PROCEDURE SPTest
AS 
BEGIN 
  insert into emptest(empid,empname,deptno)
  (1,'ravi',10);

  insert into test1(id,name,sal)
  (1,'raju',4444);

  update emptest set empname='hari' where empid=1;
END;

ステートメントでエラーが発生した場合、すべての挿入ステートメントと更新ステートメントをロールバックしたいと思います。

このストアドプロシージャにコミットとロールバックを実装するにはどうすればよいですか?

3
Pydi Raju

これは、セーブポイントを使用して行うことができます。

_create or replace PROCEDURE SPTest
AS 
BEGIN 

  -- We create a savepoint here.
  SAVEPOINT sp_sptest;

  insert into emptest(empid,empname,deptno)
  (1,'ravi',10);

  insert into test1(id,name,sal)
  (1,'raju',4444);

  update emptest set empname='hari' where empid=1;

-- If any exception occurs
EXCEPTION
  WHEN OTHERS THEN
    -- We roll back to the savepoint.

    ROLLBACK TO sp_sptest;
    -- And of course we raise again,
    -- since we don't want to hide the error.
    -- Not raising here is an error!
    RAISE; 
END;
_

通常、コミットは呼び出し元に任されます。この構成は、すべての挿入と更新が行われるか、どれも行われないことを保証するだけです。

最も外側のレベルでは、Oracleはそれ自体でロールバックを行います。つまり、SQL +コマンドラインでEXEC sptest();を実行すると、自動的に展開されます

_DECLARE
BEGIN
   sptest();
EXCEPTION
   ROLLBACK;
END;
_

ただし、呼び出し元のプロシージャに例外処理がある場合、例外はその外部レベルに到達しない可能性があるため、これは発生しません。そのため、挿入が完了し、更新によって例外がスローされ、呼び出し元によってキャッチおよび処理される可能性があるため、更新は失敗しますが、挿入は成功します。

ストアドプロシージャでプロシージャの先頭にロールバックすることで、すべてが成功するか、どれも成功しないことを保証します。

6
SQB
--Rollback on Exception else Commit;

--SET TRANSACTION READ WRITE;

 BEGIN
  SAVEPOINT ABC;  
  update table_A set column1 ='Y' where id = 69;

  update table_A set column2 ='S'  where id = 70; 

  EXCEPTION
  WHEN OTHERS THEN   
  ROLLBACK TO ABC;   
COMMIT;

END;

--createdon is of datetime type and has an exception. So rollback will happen.
0
Swati Gagare