触发器后记

   终于修改好了触发器,对于使用自治事务的行级触发器,需要判断正在修改的数据的比较,之前一直写错了,这回来个最终版本的,之前的错误是rownum引起的。

select * From (select rownum rn,表.* from 表) where rn = 2  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是否正确。

select * From (select rownum rn,表.* from 表) where rn = 2这么用

猜你喜欢

转载自bigdragon.iteye.com/blog/1436634
今日推荐