第一個表
SQL> desc new_table;
名稱 是否爲空? 類型
----------------------------------------- -------- ---------------
ID NUMBER(38)
NAME VARCHAR2(20)
用來存儲信息的表
SQL> desc history_table;
名稱 是否爲空? 類型
----------------------------------------- -------- ------------
ID NUMBER(38)
NAME VARCHAR2(20)
我想要更新new_table的時候將更新前的數據存入到history_table;有下面兩種方法:
第一種方法
create or replace trigger tr_update_newtable
before update on new_table for each row
begin
insert into history_table values(:old.id,:old.name);
end;
/
這種方式優點是比較簡單易讀,缺點是如果列特別多的話就比較頭疼。
第二種方法
使用自治事務(pragma autonomous_transaction)
create or replace trigger tr_update_newtable
before update on new_table for each row
declare
pragma autonomous_transaction;
begin
insert into history_table (select * from new_table where id =:old.id);
dbms_output.put_line(:old.id);
commit;
end tr_update_newtable;
優點是不用輸入每一列的值,缺點是如果你不提交的話(用commit),在這裏的new_table是沒有更新的。這個很容易讓人疑惑,因爲在命令行用select * from new_table你會發現已經更新了。在沒有提交時,更新後的數據存在緩存裏,在命令行裏用select,會從緩存裏調數據,而上面的程序裏的select會讀存在數據庫裏的原始表。
下面的commit是必須的,否則可能在下一次更新時出現錯誤
SQL> select * from new_table;
ID NAME
---------- ----------------------------------------
39 junjie
SQL> select * from history_table;
未選定行
SQL> update new_table set id=40;
39
已更新 1 行。
SQL> commit;
提交完成。
SQL> select * from new_table;
ID NAME
---------- ----------------------------------------
40 junjie
SQL> select * from history_table;
ID NAME
---------- ----------------------------------------
39 junjie
另外,自治事務中執行的操作是不能用rollback回滾回來的。