很简单啊,使用自治事务解决。create or replace trigger kgp2 after update on kgp2 for each row declare pragma autonomous_transaction; --定义自制失误 begin if :new.name = '5' then delete from kgp2 where name =:new.name; end if; commit; --必须提交,要不然自治事务会回滚 end kgp2;
自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。 2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据 3)自治事务提交 4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。 验证: /*create table FOO ( A NUMBER(10), B NUMBER(10), C NUMBER(10), D NUMBER(10) ) ;*/ --TRUNCATE TABLE FOO; --CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo AFTER INSERT OR UPDATE ON foo FOR EACH ROW DECLARE PRAGMA AUTONOMOUS_TRANSACTION; N_NUM NUMBER(5); BEGIN IF MOD(TRUNC(:NEW.D),2) =0 THEN DELETE FROM FOO WHERE FOO.D = :NEW.D; SELECT COUNT(1) INTO N_NUM FROM FOO; INSERT INTO BAR VALUES (N_NUM); END IF; COMMIT; END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2); 已创建 1 行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 已选择 1 行。 ChenZw> INSERT INTO FOO VALUES(2,2,2,4); 已创建 1 行。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 2 2 2 4 已选择2行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 2 2 2 4 已选择2行。 ChenZw> INSERT INTO FOO VALUES(3,3,3,4); 已创建 1 行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 3 3 3 4 已选择2行。 ChenZw> 数据没有按照预想的执行吧?
赞同。 如果必须用oracle来做,那么建议将整个过程写成一个存储过程,不建议使用触发器
自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。 2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据 3)自治事务提交 4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。 验证: /*create table FOO ( A NUMBER(10), B NUMBER(10), C NUMBER(10), D NUMBER(10) ) ;*/ --TRUNCATE TABLE FOO; --CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo AFTER INSERT OR UPDATE ON foo FOR EACH ROW DECLARE PRAGMA AUTONOMOUS_TRANSACTION; N_NUM NUMBER(5); BEGIN IF MOD(TRUNC(:NEW.D),2) =0 THEN DELETE FROM FOO WHERE FOO.D = :NEW.D; SELECT COUNT(1) INTO N_NUM FROM FOO; INSERT INTO BAR VALUES (N_NUM); END IF; COMMIT; END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2); 已创建 1 行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 已选择 1 行。 ChenZw> INSERT INTO FOO VALUES(2,2,2,4); 已创建 1 行。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 2 2 2 4 已选择2行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 2 2 2 4 已选择2行。 ChenZw> INSERT INTO FOO VALUES(3,3,3,4); 已创建 1 行。 ChenZw> COMMIT; 提交完成。 ChenZw> SELECT * FROM FOO; A B C D ---------- ---------- ---------- ---------- 1 1 1 2 3 3 3 4 已选择2行。 ChenZw> 数据没有按照预想的执行吧? 启用自制事物其实就是用来操作未提交的数据,要不然启用自制事物干嘛啊? 启用自制事物后,delete from kgp2 where name =:new.name;是可以找到并且删除。 您可以自己试下。
1)类似需求不要依赖触发器
2)使用业务端进行处理
很简单啊,使用自治事务解决。create or replace trigger kgp2
after update on kgp2
for each row
declare
pragma autonomous_transaction; --定义自制失误
begin
if :new.name = '5' then
delete from kgp2 where name =:new.name;
end if;
commit; --必须提交,要不然自治事务会回滚
end kgp2;
自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。
2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据
3)自治事务提交
4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。
验证:
/*create table FOO
(
A NUMBER(10),
B NUMBER(10),
C NUMBER(10),
D NUMBER(10)
)
;*/
--TRUNCATE TABLE FOO;
--CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo
AFTER INSERT OR UPDATE ON foo
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
N_NUM NUMBER(5);
BEGIN
IF MOD(TRUNC(:NEW.D),2) =0 THEN
DELETE FROM FOO WHERE FOO.D = :NEW.D;
SELECT COUNT(1) INTO N_NUM FROM FOO;
INSERT INTO BAR VALUES (N_NUM);
END IF;
COMMIT;
END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2);
已创建 1 行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
已选择 1 行。
ChenZw> INSERT INTO FOO VALUES(2,2,2,4);
已创建 1 行。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 4
已选择2行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 4
已选择2行。
ChenZw> INSERT INTO FOO VALUES(3,3,3,4);
已创建 1 行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
3 3 3 4
已选择2行。
ChenZw>
数据没有按照预想的执行吧?
赞同。
如果必须用oracle来做,那么建议将整个过程写成一个存储过程,不建议使用触发器
自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。
2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据
3)自治事务提交
4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。
验证:
/*create table FOO
(
A NUMBER(10),
B NUMBER(10),
C NUMBER(10),
D NUMBER(10)
)
;*/
--TRUNCATE TABLE FOO;
--CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo
AFTER INSERT OR UPDATE ON foo
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
N_NUM NUMBER(5);
BEGIN
IF MOD(TRUNC(:NEW.D),2) =0 THEN
DELETE FROM FOO WHERE FOO.D = :NEW.D;
SELECT COUNT(1) INTO N_NUM FROM FOO;
INSERT INTO BAR VALUES (N_NUM);
END IF;
COMMIT;
END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2);
已创建 1 行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
已选择 1 行。
ChenZw> INSERT INTO FOO VALUES(2,2,2,4);
已创建 1 行。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 4
已选择2行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 4
已选择2行。
ChenZw> INSERT INTO FOO VALUES(3,3,3,4);
已创建 1 行。
ChenZw> COMMIT;
提交完成。
ChenZw> SELECT * FROM FOO;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
3 3 3 4
已选择2行。
ChenZw>
数据没有按照预想的执行吧?
启用自制事物其实就是用来操作未提交的数据,要不然启用自制事物干嘛啊?
启用自制事物后,delete from kgp2 where name =:new.name;是可以找到并且删除。
您可以自己试下。