【发布时间】:2014-05-21 05:41:46
【问题描述】:
这是我要用于触发器的表:
CREATE TABLE "grace_period" (
"id" NUMBER(11) PRIMARY KEY NOT NULL,
"id_user" NUMBER(20) NOT NULL,
"date_limit" DATE NOT NULL,
"active" NUMBER(11),
"created_at" DATE NOT NULL,
"updated_at" DATE
);
我想做的是在插入之前创建一个触发器,检查新条目是否已经包含"id_user"。
如果"id_user" 存在,则为"id_user" 更新"active" 列,如果不存在,则应插入新行。
我设法将合并创建为触发器(在我将合并语句集成到 php 代码之前,将使用此触发器)但出现以下错误:
CREATE OR REPLACE TRIGGER "user_grace_changes"
BEFORE INSERT ON "grace_period"
FOR EACH ROW
BEGIN
MERGE INTO "grace_period" t1
USING dual
ON (t1."id_user" = :new."id_user")
WHEN MATCHED THEN
UPDATE SET t1."active" = :new."active"
WHEN NOT MATCHED THEN
INSERT( t1."id_user", t1."date_limit", t1."active" )
VALUES( :new."id_user", :new."date_limit", :new."active" );
END;
insert into "grace_period" ("id_user","date_limit","active")
VALUES (333, sysdate, 1);
> Informe de error - Error SQL: ORA-04091: la tabla
> PLATAFORMA.grace_period está mutando, puede que el disparador/la
> función no puedan verla ORA-06512: en "PLATAFORMA.user_grace_changes",
> línea 3 ORA-04088: error durante la ejecución del disparador
> 'PLATAFORMA.user_grace_changes' ORA-06512: en
> "PLATAFORMA.user_grace_changes", línea 3 ORA-04088: error durante la
> ejecución del disparador 'PLATAFORMA.user_grace_changes'
> 04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
> *Cause: A trigger (or a user defined plsql function that is referenced in
> this statement) attempted to look at (or modify) a table that was
> in the middle of being modified by the statement which fired it.
> *Action: Rewrite the trigger (or function) so it does not read that table.
【问题讨论】:
-
为什么不直接使用
merge语句而不是insert?为什么要使用触发器? -
嗨,Alex ...我不知道我为什么要尝试使用触发器 :( 那么合并语句会如何?。谢谢
-
看看at the Oracle docs;看看你能不能把一些东西放在一起,如果你不能让它发挥作用,把你的尝试添加到问题中(也许可以改变标题)。
-
这是得到的: MERGE INTO "grace_period" ("id_user","date_limit","active") t1 USING (SELECT 456 as "id_user", '2014-04-09 12: 00:00' 作为 "fecha",1 作为 "active" FROM dual) t2 ON (t1."id_user" = t2."id_user") WHEN MATCHED THEN UPDATE SET t1."active" = t2."active", WHEN不匹配则插入(t1.“id_user”,t1.“date_limit”,t1.“active”)值(t2.“id_user”,t2.“fecha”,t2.“active”)问候
-
请将其作为格式化代码添加到问题中,而不是作为评论。这是否有效并做你想做的事? (实际上,如果是,则可以将其添加为答案;尽管最初的问题是关于触发器的,但我不太确定 *8-) 不相关的注释-您为什么使用带引号的标识符?如果您不这样做,生活会更轻松(代码也更容易阅读)。