转自:http://blog.chinaunix.net/uid-20449297-id-1676808.html
前天,被biti_rainy大师问了一个触发器中是否可以使用commit。其实以前写了不少触发器,但是还真从来没有考虑过这个问题,当然也就没有在触发器中用过,大师为人比较严谨,开始我说好像可以吧,被说了一顿,可以就是可以,不可以就是不可以,没有中间的“好像可以”。在回来的路上,我好好回忆了这次的谈话,确实,我做学问搞技术还存在很多不好的习惯,不知道的就是不知道,知道的就是知道,没有什么好像知道的,从这些细小的方面可以看出,大师就是大师,做技术必须严谨。技术问题没有模菱两可的说法。所以决定,要想做好技术光有态度端正不行,还需要严谨的态度和打破砂锅问到底的作风,问题不过夜的好习惯,所以回来我就自己测试了一下:知道的读者可能感觉这个问题很简单,但是个人认为收获非常大,不仅仅是简单的一个问题,而是一种处事的态度,不可忽视,现在亡羊补牢,尚未晚已。以下是简单的测试过程:
SQL> CREATE TABLE TEST AS SELECT * FROM DBA_OBJECTS WHERE 1=2;
表已创建。
SQL> CREATE TABLE TEST_TEST AS SELECT OBJECT_ID,OBJECT_NAME
2 FROM TEST
3 WHERE 1=2;
表已创建。
创建两个测试表
SQL> CREATE TRIGGER TEST_TRIGGER
2 AFTER INSERT ON TEST
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO TEST_TEST(OBJECT_ID,OBJECT_NAME)
6 VALUES(:NEW.OBJECT_ID,:NEW.OBJECT_NAME);
7 END;
8 /
触发器已创建
在一个表上创建一个触发器,当想其中一个表插入数据时,自动向另外一个表中插入一条记录。
SQL> SELECT OBJECT_ID,OBJECT_NAME FROM TEST;
未选定行
SQL> INSERT INTO TEST (OBJECT_ID,OBJECT_NAME) VALUES(1,'NAME1');
已创建 1 行。
SQL> SELECT OBJECT_ID,OBJECT_NAME FROM TEST_TEST;
OBJECT_ID OBJECT_NAME
------------ --------------
1 NAME1
以上表明,触发器正常工作,当向表test1插入一条记录必定也就向test_test1表中插入相应的一条记录。
SQL> ROLLBACK;
回退已完成。
SQL> SELECT OBJECT_ID,OBJECT_NAME FROM TEST_TEST;
未选定行
当我回滚前面的事务时,trigger所发生的修改也自动rollback。
下面尝试在trigger中加入commit ,看看oracle如何处理?
SQL> CREATE TABLE TEST1 AS SELECT * FROM TEST_TEST WHERE 1=2;
表已创建。
SQL> CREATE TABLE TEST_TEST1 AS SELECT * FROM TEST_TEST WHERE 1=2;
表已创建。
SQL> CREATE OR REPLACE TRIGGER TEST1_TRIGGER
2 AFTER INSERT ON TEST1
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO TEST_TEST1(OBJECT_ID,OBJECT_NAME)
6 VALUES(:NEW.OBJECT_ID,:NEW.OBJECT_NAME);
7 COMMIT;
8 END;
9 /
触发器已创建
SQL> SELECT COUNT(*) FROM TEST1;
COUNT(*)
----------
0
SQL> SELECT COUNT(*) FROM TEST_TEST1;
COUNT(*)
----------
0
SQL> INSERT INTO TEST1 (OBJECT_ID,OBJECT_NAME) VALUES(2,'NAME2');
INSERT INTO TEST1 (OBJECT_ID,OBJECT_NAME) VALUES(2,'NAME2')
*
ERROR 位于第 1 行:
ORA-04092: COMMIT 不能在触发器中
ORA-06512: 在"TAISHAN_JAP.TEST1_TRIGGER", LINE 4
ORA-04088: 触发器 'TAISHAN_JAP.TEST1_TRIGGER' 执行过程中出错
根据报错信息可知:oracle不支持在触发器中使用commit,而触发器对相关表的修改是否生效,取决于外部的事务。当回滚该事务时,trigger发生的修改自动rollback。这样从某种程度上保证了数据的一致性。
以上仅是本人观点,如果不对之处,敬请指出,非常感谢!我的每一步都取决于大家的关注!及时纠正错误观点,努力提高个人水平。
相关推荐
§15.4 在 PL/SQL 中使用 sqlcode,sqlerrm 273 第十六章 存储过程和函数 276 §16.1 引言 276 §16.2 存储过程 276 §16.2.1 创建过程 276 §16.2.2 使用过程 278 §16.2.3 开发存储过程步骤 279 §16.2.3.1 编辑...
§15.4 在 PL/SQL 中使用 sqlcode,sqlerrm 273 第十六章 存储过程和函数 276 §16.1 引言 276 §16.2 存储过程 276 §16.2.1 创建过程 276 §16.2.2 使用过程 278 §16.2.3 开发存储过程步骤 279 §16.2.3.1 编辑...
31、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 21 33、数字转字符有多少种方式,分别是什么 22 34、Java创建对象有几种方式 22 35、写出验证...
MySQL可以使用check约束,但check约束对数据验证没有任何作用。 create table temp( id int auto_increment, name varchar(20), age int, primary key(id), /*check约束*/ check(age > 20) ); 上面check约束要求age...
6.6.3 使用触发器执行基于值的审核 200 6.6.4 细粒度审核(FGA) 201 6.7 本章知识点回顾 204 6.8 自测题 205 6.9 自测题答案 208 第Ⅱ部分 SQL 211 第7章 DDL和模式对象 213 7.1 分类主要的数据库对象 214 ...
6.6.3 使用触发器执行基于值的审核 200 6.6.4 细粒度审核(FGA) 201 6.7 本章知识点回顾 204 6.8 自测题 205 6.9 自测题答案 208 第Ⅱ部分 SQL 211 第7章 DDL和模式对象 213 7.1 分类主要的数据库对象 214 ...
COMMIT 和 ROLLBACK 命令 8-9 PL/SQL 8-10 管理 PL/SQL 对象 8-11 PL/SQL 对象 8-12 函数 8-13 过程 8-14 程序包 8-15 程序包说明和程序包体 8-16 内置程序包 8-17 触发器 8-18 触发事件 8-19 锁定 8-20 ...
在精度需求上,根据使用需要,在各项数据的输入、输出及传输过程中,由于本系统使用了数摞结构,可以满足各种精度的需求。 3.3.3时间需求 在软件方面,响应时间、更新处理时间都比较快且迅速,完全满足用户要求...
§3.2.2 在参数值中使用特殊字符 65 §3.2.3 修改参数值 66 §3.2.4 显示当前参数值 69 §3.2.5 参数的使用 69 §3.2.6 参数的类型 69 §3.2.7 不能在参数文件中指定的参数 70 §3.2.8 当参数指定错误时怎么办? 70 ...
在异构环境中使用事务协调服务 .......... 178 监控协调事务和参与者 .......... 179 DTM 管理和故障排除 .......... 179 事务和控制线程 .......... 179 获取有关分布式事务的信息 .......... 181 执行外部事务的...