终于修改好了触发器,对于使用自治事务的行级触发器,需要判断正在修改的数据的比较,之前一直写错了,这回来个最终版本的,之前的错误是rownum引起的。
===============================================
CREATE OR REPLACE TRIGGER TB_PER_POSITONLEVEL_TRI
AFTER INSERT OR UPDATE OF c_effectivedate,c_postionlevel,c_postioncluster OR DELETE ON TB_PER_POSITONLEVEL
FOR EACH ROW
DECLARE
position_effdate DATE;
position_level varchar2(64);
position_order varchar2(64);
position_oid varchar2(128);
cou NUMBER(3);
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
--SELECT COUNT(*) INTO cou FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC);
--INSERT INTO A_TEMP VALUES(cou);
IF inserting THEN
SELECT COUNT(*) INTO cou FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC);
-- INSERT INTO A_TEMP VALUES('行级别触发器after');
--INSERT INTO A_TEMP VALUES(position_oid);
--INSERT INTO A_TEMP VALUES( to_char(position_effdate,'fmdd month yyyy') );
--INSERT INTO A_TEMP VALUES(position_level);
--INSERT INTO A_TEMP VALUES(position_order);
--INSERT INTO A_TEMP VALUES(cou);
--以前有记录,插入记录需要与以往记录的最大日期比较。
IF cou <> 0 THEN
SELECT CASE WHEN :new.c_oid = c_oid THEN :NEW.c_postionlevel ELSE c_postionlevel END INTO position_level FROM (SELECT a.c_oid, a.c_postionlevel FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT c_effectivedate INTO position_effdate FROM (SELECT a.c_oid,a.c_effectivedate FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT CASE WHEN :new.c_oid = c_oid THEN :new.c_postioncluster ELSE c_postioncluster END INTO position_order FROM (SELECT a.c_oid,a.c_postioncluster FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT c_oid INTO position_oid FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
IF position_effdate <= :NEW.c_effectivedate THEN
--INSERT INTO A_TEMP VALUES('插入的是最新的');
UPDATE tb_inf_employee t SET t.c_positionlevel = :NEW.c_postionlevel,
t.c_positionorder = :NEW.c_postioncluster WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
ELSIF position_effdate > :NEW.c_effectivedate THEN
--INSERT INTO A_TEMP VALUES('插入的不是最新的,没有影响');
UPDATE tb_inf_employee t SET t.c_positionlevel = position_level,
t.c_positionorder = position_order WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
END IF;
--以前没有记录,插入一条记录。
IF cou = 0 THEN
UPDATE tb_inf_employee t SET t.c_positionlevel = :NEW.c_postionlevel,
t.c_positionorder = :NEW.c_postioncluster WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
IF deleting THEN
SELECT COUNT(*) INTO cou FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :OLD.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC);
-- INSERT INTO A_TEMP VALUES('行级别触发器after');
--INSERT INTO A_TEMP VALUES(position_oid);
-- INSERT INTO A_TEMP VALUES( to_char(position_effdate,'fmdd month yyyy') );
-- INSERT INTO A_TEMP VALUES(position_level);
--INSERT INTO A_TEMP VALUES(position_order);
-- IF(:OLD.c_oid == )
--不是最后一条记录,排除:old.oid所在记录,排序取最大值
IF cou <> 1 THEN
SELECT c_postionlevel INTO position_level FROM (SELECT a.c_postionlevel FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_oid <> :OLD.c_oid AND a.c_empoid = b.c_employeeid AND a.c_empoid = :OLD.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT c_effectivedate INTO position_effdate FROM (SELECT a.c_effectivedate FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_oid NOT IN (:OLD.c_oid) AND a.c_empoid = b.c_employeeid AND a.c_empoid = :OLD.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT c_postioncluster INTO position_order FROM (SELECT a.c_postioncluster FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_oid NOT IN (:OLD.c_oid) AND a.c_empoid = b.c_employeeid AND a.c_empoid = :OLD.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT c_oid INTO position_oid FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :OLD.c_empoid AND a.c_oid <> :old.c_oid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
UPDATE tb_inf_employee t SET t.c_positionlevel = position_level,
t.c_positionorder = position_order WHERE t.c_employeeid = :OLD.C_EMPOID;
END IF;
--删除最后一条记录,都置空
IF cou = 1 THEN
UPDATE tb_inf_employee t SET t.c_positionlevel = '',
t.c_positionorder = '' WHERE t.c_employeeid = :OLD.C_EMPOID;
END IF;
END IF;
IF UPDATing THEN
INSERT INTO A_TEMP VALUES('更新开始=====================================');
--更新之前的,最大生效日期,和最大生效日期对应的id
SELECT c_effectivedate INTO position_effdate FROM (SELECT a.c_effectivedate FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
INSERT INTO A_TEMP VALUES('更新之前的原排序最大生效日期:');
INSERT INTO a_temp VALUES(position_effdate);
SELECT c_oid INTO position_oid FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
INSERT INTO A_TEMP VALUES('更新之前的原排序最大记录oid:');
INSERT INTO a_temp VALUES(position_oid);
--未修改生效时间,未影响排序
IF :NEW.c_effectivedate = :OLD.c_effectivedate THEN
INSERT INTO A_TEMP VALUES(' 1 此次修改,未修改生效日期!');
SELECT CASE WHEN :new.c_oid = c_oid THEN :NEW.c_postionlevel ELSE c_postionlevel END INTO position_level FROM (SELECT a.c_oid, a.c_postionlevel FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT CASE WHEN :new.c_oid = c_oid THEN :new.c_postioncluster ELSE c_postioncluster END INTO position_order FROM (SELECT a.c_oid,a.c_postioncluster FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
--SELECT c_oid INTO position_oid FROM (SELECT a.c_oid FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
--INSERT INTO A_TEMP VALUES('行级别触发器after');
--INSERT INTO A_TEMP VALUES(position_oid);
-- INSERT INTO A_TEMP VALUES( to_char(position_effdate,'fmdd month yyyy') );
-- INSERT INTO A_TEMP VALUES(position_level);
-- INSERT INTO A_TEMP VALUES(position_order);
UPDATE tb_inf_employee t SET t.c_positionlevel = position_level,
t.c_positionorder = position_order WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
--修改生效时间,以前的查询结果的生效时间最大值不是修改的项,修改的生效日期 大于等于 原排序结果的生效日期,取新的
IF :NEW.c_effectivedate <> :OLD.c_effectivedate AND position_oid <> :OLD.c_oid AND :NEW.c_effectivedate >= position_effdate THEN
INSERT INTO A_TEMP VALUES(' 2 此次修改,修改了生效日期!且原排序最大值不是dirty!且改后的生效日期 大于 原排序最大生效日期!');
UPDATE tb_inf_employee t SET t.c_positionlevel = :NEW.c_postionlevel,
t.c_positionorder = :new.c_postioncluster WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
--修改生效时间,以前的查询结果的生效时间最大值不是修改的项,修改的生效日期 小于 原排序结果的生效日期,取原生效结果的
IF :NEW.c_effectivedate <> :OLD.c_effectivedate AND position_oid <> :OLD.c_oid AND :NEW.c_effectivedate < position_effdate THEN
INSERT INTO A_TEMP VALUES(' 3 此次修改,修改了生效日期!且原排序最大值不是dirty!且改后的生效日期 小于 原排序最大生效日期!');
SELECT CASE WHEN :new.c_oid = c_oid THEN :NEW.c_postionlevel ELSE c_postionlevel END INTO position_level FROM (SELECT a.c_oid, a.c_postionlevel FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
SELECT CASE WHEN :new.c_oid = c_oid THEN :new.c_postioncluster ELSE c_postioncluster END INTO position_order FROM (SELECT a.c_oid,a.c_postioncluster FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE ROWNUM =1 ;
--INSERT INTO A_TEMP VALUES('行级别触发器after');
--INSERT INTO A_TEMP VALUES(position_oid);
-- INSERT INTO A_TEMP VALUES( to_char(position_effdate,'fmdd month yyyy') );
-- INSERT INTO A_TEMP VALUES(position_level);
-- INSERT INTO A_TEMP VALUES(position_order);
UPDATE tb_inf_employee t SET t.c_positionlevel = position_level,
t.c_positionorder = position_order WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
--修改生效时间,以前的查询结果的最大生效日期就是修改的项,且修改后的日期 大于等于原来排序结果生效日期,取新的
IF :NEW.c_effectivedate <> :OLD.c_effectivedate AND position_oid = :OLD.c_oid AND :NEW.c_effectivedate >=position_effdate THEN
INSERT INTO A_TEMP VALUES(' 4 (调大最大生效日期的日期)此次修改,修改了生效日期!且原排序最大值是dirty!且改后的生效日期 >= 原排序最大生效日期!');
UPDATE tb_inf_employee t SET t.c_positionlevel = :NEW.c_postionlevel,
t.c_positionorder = :new.c_postioncluster WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
--修改生效时间,以前的查询结果的生效时间最大值是修改的项,修改的生效日期 小于 原排序结果的生效日期,取原生效结果的第二行记录,然后比较
IF :NEW.c_effectivedate <> :OLD.c_effectivedate AND position_oid = :OLD.c_oid AND :NEW.c_effectivedate <position_effdate THEN
INSERT INTO A_TEMP VALUES(' 5 (调小最大生效日期的日期,此时与第二大生效日期比较)此次修改,修改了生效日期!且原排序最大值是dirty!且改后的生效日期 < 原排序最大生效日期!');
--SELECT c_postionlevel INTO position_level FROM (SELECT ROWNUM rn,a.c_oid, a.c_postionlevel FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE rn = 2 ;
--SELECT c_postioncluster INTO position_order FROM (SELECT ROWNUM rn,a.c_oid,a.c_postioncluster FROM TB_PER_POSITONLEVEl a,tb_inf_employee b WHERE a.c_empoid = b.c_employeeid AND a.c_empoid = :NEW.c_empoid ORDER BY nvl(a.C_EFFECTIVEDATE,TO_DATE('1900/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') ) DESC,a.c_operatetime DESC) WHERE rn = 2 ;
SELECT C_EFFECTIVEDATE INTO position_effdate
FROM (SELECT ROWNUM RN, C_EFFECTIVEDATE
FROM (SELECT A.C_EFFECTIVEDATE
FROM TB_PER_POSITONLEVEL A, TB_INF_EMPLOYEE B
WHERE A.C_EMPOID = B.C_EMPLOYEEID
AND A.C_EMPOID = :NEW.c_empoid
ORDER BY NVL(A.C_EFFECTIVEDATE,
TO_DATE('1900/01/01 00:00:00',
'YYYY/MM/DD HH24:MI:SS')) DESC,
A.C_OPERATETIME DESC))
WHERE RN = 2;
SELECT c_postioncluster INTO position_order
FROM (SELECT ROWNUM RN, c_postioncluster
FROM (SELECT A.c_postioncluster
FROM TB_PER_POSITONLEVEL A, TB_INF_EMPLOYEE B
WHERE A.C_EMPOID = B.C_EMPLOYEEID
AND A.C_EMPOID = :NEW.c_empoid
ORDER BY NVL(A.c_postioncluster,
TO_DATE('1900/01/01 00:00:00',
'YYYY/MM/DD HH24:MI:SS')) DESC,
A.C_OPERATETIME DESC))
WHERE RN = 2;
SELECT c_postionlevel INTO position_level
FROM (SELECT ROWNUM RN, c_postionlevel
FROM (SELECT A.c_postionlevel
FROM TB_PER_POSITONLEVEL A, TB_INF_EMPLOYEE B
WHERE A.C_EMPOID = B.C_EMPLOYEEID
AND A.C_EMPOID = :NEW.c_empoid
ORDER BY NVL(A.c_postionlevel,
TO_DATE('1900/01/01 00:00:00',
'YYYY/MM/DD HH24:MI:SS')) DESC,
A.C_OPERATETIME DESC))
WHERE RN = 2;
--%%如果新记录日期 < 第二个最大的,取第二个最大的。
IF :NEW.c_effectivedate < position_effdate THEN
INSERT INTO A_TEMP VALUES(' 5.1调小最大生效日期的日期 < 原排序第二条最大记录');
INSERT INTO A_TEMP VALUES(position_level);
UPDATE tb_inf_employee t SET t.c_positionlevel = position_level,
t.c_positionorder = position_order WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
--%%如果新记录日期 > =第二个最大的,取新纪录 。
IF :NEW.c_effectivedate >= position_effdate THEN
INSERT INTO A_TEMP VALUES('修改生效日期,原排序最大值是dirty,找第二条最大记录,且新日期大于第二条最大记录');
UPDATE tb_inf_employee t SET t.c_positionlevel = :NEW.c_postionlevel,
t.c_positionorder = :new.c_postioncluster WHERE t.c_employeeid = :NEW.C_EMPOID;
END IF;
END IF;
INSERT INTO A_TEMP VALUES('更新ENDING============================================');
END IF;
COMMIT;
END TB_PER_POSITONLEVEL_TRI;
====================================================================
一定要注意有order by 的rownum的位置。蓝色字体可以查看rownum是否正确。