Oracle_Trigger:基于INSERT / UPDATE的列的自动更新

时间:2016-05-26 13:29:11

标签: oracle database-trigger

对于大多数人来说,这可能看起来很简单,但我是Oracle DB的初学者。 已使用以下脚本创建表 -

CREATE TABLE PLAN_TABLE
(
    PL_ID DECIMAL(10,0) PRIMARY KEY NOT NULL
   ,PL_NAME VARCHAR2(300) DEFAULT NULL
   ,UPDATED_TS TIMESTAMP DEFAULT SYSDATE NOT NULL
   ,DELETE_FLAG DECIMAL(10,0) DEFAULT 0 NOT NULL
);

要求对于插入表中的任何新记录都要有UPDATED_TS的SYSDATE,以及DELETE_FLAG更新为1时的情况。是否可以通过触发器完成? 以下触发器已创建 -

CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
BEFORE INSERT ON PLAN_TABLE
FOR EACH ROW 
BEGIN 
SELECT SYSDATE INTO :new.UPDATED_TS FROM DUAL; 
dbms_output.put_line('Inserted');
END;
/

在将记录插入表格时遇到以下错误 - 错误:ORA-04091:表I60_SCH04.PLAN_TABLE正在变异,触发器/函数可能看不到它

请你帮忙告诉我,我在哪里犯了错误?有没有更好的方法来实现基于INSERT / UPDATE的要求?

1 个答案:

答案 0 :(得分:1)

您获得的实际错误是由于您尝试从实际上正在更改的表中进行选择。为了防止这个问题,有几种方法,但在你的情况下,事情非常简单。

SYSDATE是一个函数,你可以直接调用PL / SQL块(实际上是一个触发器)并使用返回的值来更新设置列值

CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
  BEFORE INSERT ON PLAN_TABLE
  FOR EACH ROW 
BEGIN 
  :new.UPDATED_TS := sysdate; 
  dbms_output.put_line('Inserted');
END;
/

好的,这涵盖了插入部分。

更新 - 再一次,许多选项。可以是 - 将您的触发器更改为在PLAN_TABLE之前插入或更新。

在这种情况下,无论何时发出更新或插入 - 都会针对每一行触发此触发器并相应地更新日期列。

当然,您可以使用触发器中可用的特定检查,例如

IF INSERTING OR UPDATING('DELETE_FLAG') THEN
    ...
END IF;

并编写您需要的逻辑代码。