更新触发器不更新列中的时间戳(更新操作)

时间:2019-03-13 15:24:31

标签: sql oracle

在对表启用了触发器的情况下更新表列时,触发器不起作用...

      CREATE OR REPLACE Trigger TR_FinlStatAssetDesignation_U
    BEFORE Update
    on FINLSTATASSETDESIGNATION FOR EACH ROW
       DECLARE
       v_AtDateTime  TIMESTAMP(3);
       v_LogOperation  NUMBER(3,0);
       v_UserName  VARCHAR2(255);
       v_AppName  VARCHAR2(255);
       SWV_error NUMBER(10,0) DEFAULT 0;
    BEGIN

       begin
          select   USERNAME INTO v_UserName FROM v$session  WHERE (audsid = SYS_CONTEXT('userenv','sessionid')) AND ROWNUM <=1;
          EXCEPTION
          WHEN NO_DATA_FOUND THEN
             NULL;
       end;

       SELECT program INTO v_AppName FROM v$session WHERE audsid=userenv('sessionid'); 
       if (LENGTH(v_AppName) = 0) then 
          v_AppName := 'Unknown';
       end if; 

       SELECT distinct TO_CHAR(SYSTIMESTAMP,'DD-MON-YY hh24:mi:SS.FF AM') INTO v_AtDateTime FROM dual;


       if UPDATING('FinlStatAssetDesignation') then
          RAISE_APPLICATION_ERROR(-20000,'Invalid attempt to update OID FinlStatAssetDesignation in FinlStatAssetDesignation');
          /*    
    ROLLBACK */
    return;
       end if;

       if not UPDATING('UpdDate') then
          SWV_error := 0;
          begin
             UPDATE FinlStatAssetDesignation a SET(UpdDate) =(SELECT distinct v_AtDateTime FROM dual where a.FinlStatAssetDesignation = :NEW.FinlStatAssetDesignation)
             WHERE ROWID IN(SELECT a.ROWID FROM FinlStatAssetDesignation a where a.FinlStatAssetDesignation = :NEW.FinlStatAssetDesignation);
             EXCEPTION
             WHEN OTHERS THEN
                SWV_error := SQLCODE;
          end;
          if SWV_error <> 0 then
             /* 
    ROLLBACK */
    return;
          end if;
       end if;
       END;

        QL>  select * from finlstatassetdesignation;

FINLSTATAS FINLSTATASSETDESIGNATIONDESC                       UPDOPERATION
---------- -------------------------------------------------- ------------
UPDDATE
---------------------------------------------------------------------------
one19      anything                                                      0
01-JAN-17 08.00.00.000000 AM

SQL>  update finlstatassetdesignation set finlstatassetdesignationdesc ='nothing';

1 row updated.

SQL> select * from finlstatassetdesignation;

FINLSTATAS FINLSTATASSETDESIGNATIONDESC                       UPDOPERATION
---------- -------------------------------------------------- ------------
UPDDATE
---------------------------------------------------------------------------
one19      nothing                                                       0
01-JAN-17 08.00.00.000000 AM


    SQL> desc finlstatassetdesignation;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     FINLSTATASSETDESIGNATION                  NOT NULL CHAR(10 CHAR)
     FINLSTATASSETDESIGNATIONDESC              NOT NULL VARCHAR2(50 CHAR)
     UPDOPERATION                              NOT NULL NUMBER(10)
     UPDDATE                                   NOT NULL TIMESTAMP(6)

尝试更新FINLSTATASSETDESIGNATIONDESC列成功,但是未更新UPDDATE列中的时间戳记

请帮助...修复此触发器...

在对表启用了触发器的情况下更新表列时,触发器不起作用...

1 个答案:

答案 0 :(得分:1)

通常,当您实际上想写时间戳时,写字符串(即TO_CHAR(SYSTIMESTAMP,'DD-MM-YY hh24:mi:SS.FF AM') INTO v_AtDateTime)是一个坏主意。

您的代码中有几个弱点,根据我的理解,您可以编写得更简单:

CREATE OR REPLACE TRIGGER TR_FinlStatAssetDesignation_U
    BEFORE UPDATE
    ON FINLSTATASSETDESIGNATION FOR EACH ROW

    BEGIN

   IF UPDATING('FinlStatAssetDesignation') THEN
      RAISE_APPLICATION_ERROR(-20000,'Invalid attempt to update OID FinlStatAssetDesignation in FinlStatAssetDesignation');
      -- Rather strange if a column has the same name as the table
   END IF;

   IF NOT UPDATING('UpdDate') THEN
     :NEW.UpdDate := SYSTIMESTAMP;
   END IF;
END;

代码中的所有其他内容都是多余的。垃圾。

如果您在某处需要用户名,只需写USER而不是

select   USERNAME INTO v_UserName 
FROM v$session  
WHERE (audsid = SYS_CONTEXT('userenv','sessionid')) AND ROWNUM <=1;

对于应用程序,使用NVL(SYS_CONTEXT('USERENV', 'CLIENT_PROGRAM_NAME'), 'Unknown')代替

  SELECT program INTO v_AppName FROM v$session WHERE audsid=userenv('sessionid'); 
   if (LENGTH(v_AppName) = 0) then 
      v_AppName := 'Unknown';
   end if;