トランザクションの処理中に現在のポイントにマークを付け、名前を指定するには、SAVEPOINT
文を使用します。マークを設定したそれぞれの点をセーブポイントと呼びます。たとえば、次の文では、start_deleteというセーブポイントを設定しています。
EXEC SQL SAVEPOINT start_delete;
セーブポイントを設定すると、長いトランザクションを分割できるため、複雑なプロシージャでもうまく制御できます。たとえば、単一のトランザクションが複数のファンクションを実行しているときに、それぞれのファンクションの前にセーブポイントを設定できます。その結果、1つのファンクションが失敗しても、簡単にOracleデータを前の状態にリストアし、リカバリしてから、ファンクションを再実行できます。
トランザクションの一部を取り消すには、セーブポイントをROLLBACK
文とそのTO SAVEPOINT
句とともに使用します。TO SAVEPOINT
句を使用すると、現行のトランザクションの途中の文までロールバックできるため、変更をすべて取り消す必要はありません。具体的には、ROLLBACK TO SAVEPOINT
文により次の処理が実行されます。
指定したセーブポイントがマークされた以降のデータベースへの変更を取り消します。
指定したセーブポイント以降のセーブポイントをすべて消去します。
指定したセーブポイントがマークされた以降に取得された行および表のロックをすべて解除します。
次の例では、MAIL_LIST
表にアクセスして新しいリストを挿入し、古いリストを更新して、アクティブでない(少数の)リストを削除しています。削除後、SQLCAのSQLERRD(3)をチェックして、削除された行数を調べます。行数が予想以上に多い場合は、セーブポイントstart_deleteまでロールバックして、その削除のみを取り消します。
FOR EACH new customer display 'Customer number? '; read cust_number; display 'Customer name? '; read cust_name; EXEC SQL INSERT INTO MAIL_LIST (CUSTNO, CNAME, STAT) VALUES (:cust_number, :cust_name, 'ACTIVE'); ENDFOR; FOR EACH revised status display 'Customer number? '; read cust_number; display 'New status? '; read new_status; EXEC SQL UPDATE MAIL_LIST SET STAT = :new_status WHERE CUSTNO = :cust_number; ENDFOR; -- mark savepoint EXEC SQL SAVEPOINT start_delete; EXEC SQL DELETE FROM MAIL_LIST WHERE STAT = 'INACTIVE'; IF sqlca.sqlerrd(3) < 25 THEN -- check number of rows deleted display 'Number of rows deleted is ', sqlca.sqlerrd(3); ELSE display 'Undoing deletion of ', sqlca.sqlerrd(3), ' rows'; EXEC SQL WHENEVER SQLERROR GOTO sql_error; EXEC SQL ROLLBACK TO SAVEPOINT start_delete; ENDIF; EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL COMMIT WORK RELEASE; exit program; sql_error: EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK RELEASE; display 'Processing error'; exit program with an error;
ROLLBACK TO SAVEPOINT
文では、RELEASE
オプションを指定できないことに注意してください。
あるセーブポイントまでロールバックすると、そのセーブポイント以降に設定されたセーブポイントはすべて消去されます。ただし、ロールバックしたセーブポイントはそのまま残ります。たとえば、5つのセーブポイントを設定しているときに3番目のセーブポイントまでロールバックすると、4番目と5番目のセーブポイントのみ消去されます。COMMIT
文またはROLLBACK
文では、すべてのセーブポイントが消去されます。
デフォルトでは、ユーザー・セッションごとのアクティブなセーブポイントの数は、5つに制限されています。アクティブなセーブポイントとは、最後のコミットまたはロールバック以降に設定されたセーブポイントです。データベース管理者(DBA)は、Oracleの初期化パラメータSAVEPOINTS
の値を増やして、この制限を引き上げることができます。2つのセーブポイントに同じ名前を付けると、最初のセーブポイントが消去されます。