【问题标题】:Update trigger not updating timestamp(update operation) in column更新触发器不更新列中的时间戳(更新操作)
【发布时间】:2019-03-13 23:51:26
【问题描述】:

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

      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 中的时间戳

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

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

【问题讨论】:

  • 您正在将字符串 (TO_CHAR(SYSTIMESTAMP, …)) 提取到时间戳变量 v_AtDateTime 中。还有,UpdDate 列的类型是什么?
  • @Aleksej,它是问题中给出的TIMESTAMP

标签: sql oracle


【解决方案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; 

【讨论】:

  • @Wernfried...谢谢它就像一个魅力...我已经为我的用例做了更多修改..
猜你喜欢
  • 1970-01-01
  • 2014-09-30
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多