一直以來對oracle中嵌套的begin...end語句塊都有一個疑問,
就是不清楚嵌套在同一個begin...end中的兩個begin...end語句塊是不是能算作同一個事務.
今天終於有點搞明白這個問題了,在此做個記錄.
1.創建兩個測試用表:
create table TEST1
(
ID VARCHAR2(10),
NAME VARCHAR2(10)
)
insert into TEST1 (ID, NAME)
values ('1', '張三修改');
insert into TEST1 (ID, NAME)
values ('2', '李四');
insert into TEST1 (ID, NAME)
values ('3', '趙五');
create table TEST2
(
ID VARCHAR2(10),
AGE number
)
insert into TEST2 (ID, AGE)
values ('1', '20');
insert into TEST2 (ID, AGE)
values ('2', '21');
2.用於執行測試的sql
DECLARE
AS_rowcount NUMBER(10) := 0;
BEGIN
BEGIN --1
UPDATE TEST1 T SET T.NAME = T.NAME || '修改' WHERE T.ID = '1';
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RETURN;
END;
AS_rowcount := 0;
BEGIN --2
SELECT COUNT(1) INTO AS_rowcount FROM TEST2 T WHERE T.ID = 3;
IF AS_rowcount = 0 THEN
ROLLBACK;
END IF;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RETURN;
END;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RETURN;
END;
3.sql執行結果:
1:第一個begin...end語句塊
2:第二個begin...end語句塊
(1)
因為 2 中的 if 條件成立,
所以 1 中的sql語句最終也會回滾,update語句最終不會執行成功;
(2)
如果 1 中的update語句后加上commit語句,修改為
UPDATE TEST1 T SET T.NAME = T.NAME || '修改' WHERE T.ID = '1';
commit;
則盡管 2 中的 if 條件成立,1 中的update語句執行的結果已經提交,也不會回滾了.
總結:
自己把oracle中的事務和begin...end語句塊理解混了,
以為begin...end語句中的內容就是同一個事務,一旦中途報錯,所有操作就會回滾.
現在終於明白了:當中途沒有commit語句,最后的end之前commit的時候確實可以算作是同一個事務的內容,中途報錯全部回滾.
但是一旦中途出現commit語句的話,commit后面的語句就算報錯,已經commit的內容也不會回滾了.