使用触发器做到在一个表更新记录时将更新前的记录存入另一个表

来源:互联网 发布:python入门书籍推荐 编辑:程序博客网 时间:2024/06/05 15:16

第一个表

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_newtablebefore update on new_table for each rowbegin  insert into history_table values(:old.id,:old.name);end;/

这种方式优点是比较简单易读,缺点是如果列特别多的话就比较头疼。

第二种方法

使用自治事务(pragma autonomous_transaction)

create or replace trigger tr_update_newtablebefore update on new_table for each rowdeclare  pragma autonomous_transaction;begininsert 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 junjieSQL> select * from history_table;未选定行SQL> update new_table set id=40;39已更新 1 行。SQL> commit;提交完成。SQL> select * from new_table;        ID NAME---------- ----------------------------------------        40 junjieSQL> select * from history_table;        ID NAME---------- ----------------------------------------        39 junjie

另外,自治事务中执行的操作是不能用rollback回滚回来的。