保存點(diǎn)(SAVEPOINT)是事務(wù)處理過程中的一個(gè)標(biāo)志,與回滾命令(ROLLBACK)結(jié)合使用,主要的用途是允許用戶將某一段處理回滾而不必回滾整個(gè)事務(wù),這在PL/SQL開發(fā)中還是很有用處的。
下面的例子中,把SAVEPOINT標(biāo)記在INSERT語句之前,如果這條INSERT語句試圖將重復(fù)的數(shù)據(jù)保存到EMP表中的話,將觸發(fā)執(zhí)行預(yù)先定義的DUP_VAL_ON_INDEX例外處理,在這里面的ROLLBACK TO do_insert命令將回滾上面的那條INSERT操作,而不會影響前面的任何操作。
DECLARE
emp_id emp.empno%TYPE;
BEGIN
UPDATE emp SET ... WHERE empno = emp_id;
DELETE FROM emp WHERE ...
...
SAVEPOINT do_insert;
INSERT INTO emp VALUES (emp_id, ...);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO do_insert;
END;
如果你定義了多個(gè)savepoint,當(dāng)你指定回滾到某個(gè)savepoint時(shí),那么回滾操作將回滾這個(gè)savepoint后面的所有操作(即使后面可能標(biāo)記了N個(gè)savepoint)。例如,在一段處理中
你定義了五個(gè)savepoint,從第三個(gè)savepoint回滾,后面的第四、第五個(gè)標(biāo)記的操作都將被回滾,如果不使用ROLLBACK TO savepoint_name而使用ROLLBACK,將會滾整個(gè)事務(wù)處理。
如果你在遞歸子程序里面定義了一個(gè)savepoint, 如果每一個(gè)遞歸層都設(shè)置了SAVEPOINT. 此時(shí), 你只能回滾到最近的一個(gè)savepoint.
Savepoint的聲明可以在同一個(gè)事務(wù)處理里面重復(fù)定義. 它的作用就是把savepoint從上一個(gè)位置轉(zhuǎn)移到目前的位置. 因而,執(zhí)行回滾也只回滾到最近的savepoint.
下面是一個(gè)例子:
BEGIN
...
SAVEPOINT my_point;
UPDATE emp SET ... WHERE empno = emp_id;
...
SAVEPOINT my_point; -- move my_point to current point
INSERT INTO emp VALUES (emp_id, ...);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO my_point;
END;
另外,Oracle沒有對每個(gè)session里面可以使用的savepoint個(gè)數(shù)做限制.