最近工作原因,研究了一个十分简单的触发器,行级触发。
一直觉得写的不对,搞了一天,才发现是程序的问题。
CREATE OR REPLACE TRIGGER YSSB
-- 关于Before还是After
--一般来说效果一样,无论使用before与after,均可读取:old与:new的记录信息
--触发时机为before时,能修改:new的记录信息,不能修改:old记录信息
--触发时机为after时,:new与:old的信息均不能被修改
BEFORE UPDATE OF NODE_FLAG1 OR INSERT OR DELETE ON SYS_FLOW_RESR
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
I INTEGER;
/*数据库事务是一种单元操作,要么是全部操作都成功,要么全部失败。在Oracle中,一个事务是从执行第一个数据管理语言(DML)语句开始,直到执行一个COMMIT语句,提交保存这个事务,或者执行一个ROLLBACK语句,放弃此次操作结束。
针对这种困境,Oracle提供了一种便捷的方法,即自治事务。自治事务从当前事务开始,在其自身的语境中执行。它们能独立地被提交或重新运行,而不影响正在运行的事务。正因为这样,它们成了编写错误日志表格的理想形式。在事务中检测到错误时,您可以在错误日志表格中插入一行并提交它,然后在不丢失这次插入的情况下回滚主事务。
触发无法包含COMMIT语句,除非有PRAGMA AUTONOMOUS_TRANSACTION标记。但是,只有触发中的语句才能被提交,主事务则不行。
*/
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF (:OLD.NODE_ID = 'YSSH' OR :NEW.NODE_ID = 'YSSH') THEN
CASE
WHEN UPDATING('node_flag1') THEN
SELECT COUNT(1)
INTO I
FROM SYS_FLOW_RESR
WHERE NODE_ID = 'YSXD'
AND UNIT_BH = :NEW.UNIT_BH
AND FLOW_DATE = :NEW.FLOW_DATE;
IF I = 1 THEN
UPDATE SYS_FLOW_RESR
SET NODE_FLAG1 = :new.node_flag1
WHERE NODE_ID = 'YSXD'
AND UNIT_BH = :NEW.UNIT_BH
AND FLOW_DATE = :NEW.FLOW_DATE;
COMMIT;
ELSE
INSERT INTO SYS_FLOW_RESR
(UNIT_BH, UNIT_TYPE, FLOW_DATE, NODE_ID, YSBB_BH, NODE_FLAG1)
VALUES
(:NEW.UNIT_BH,
'1',
:NEW.FLOW_DATE,
'YSXD',
'0000',
:NEW.NODE_FLAG1);
COMMIT;
END IF;
WHEN INSERTING THEN
SELECT COUNT(1)
INTO I
FROM SYS_FLOW_RESR
WHERE NODE_ID = 'YSXD'
AND UNIT_BH = :NEW.UNIT_BH
AND FLOW_DATE = :NEW.FLOW_DATE;
IF I = 1 THEN
UPDATE SYS_FLOW_RESR
SET NODE_FLAG1 = :NEW.NODE_FLAG1
WHERE NODE_ID = 'YSXD'
AND UNIT_BH = :NEW.UNIT_BH
AND FLOW_DATE = :NEW.FLOW_DATE;
COMMIT;
ELSE
INSERT INTO SYS_FLOW_RESR
(UNIT_BH, UNIT_TYPE, FLOW_DATE, NODE_ID, YSBB_BH, NODE_FLAG1)
VALUES
(:NEW.UNIT_BH,
'1',
:NEW.FLOW_DATE,
'YSXD',
'0000',
:NEW.NODE_FLAG1);
COMMIT;
END IF;
WHEN DELETING THEN
UPDATE SYS_FLOW_RESR
SET NODE_FLAG1 = '0'
WHERE NODE_ID = 'YSXD'
AND UNIT_BH = :OLD.UNIT_BH
AND FLOW_DATE = :OLD.FLOW_DATE;
COMMIT;
END CASE;
END IF;
END;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26869973/viewspace-723342/ ,如需转载,请注明出处,否则将追究法律责任。