第一个表
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回滚回来的。