对于大多数人来说,这可能看起来很简单,但我是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的要求?
答案 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;
并编写您需要的逻辑代码。