我正在编写触发器,以确保只有一种类型的货币可以设置为官方货币。我的意图是编写一个“插入或更新前”触发器。插入部分运行良好,但问题是编码更新部分,因为当我尝试更新表时,我收到ORA-04091 "mutanting table“。你有什么想法吗?
表(只能设置一条记录为'Y'):
mon_id mon_description mon_official
----------------------------------------------
E EUR N
D DOL N
P PES Y
触发器:
CREATE OR REPLACE TRIGGER mon_oficial_ins_trg
BEFORE
INSERT OR UPDATE
ON monedas
FOR EACH ROW
DECLARE
v_count NUMBER(8);
BEGIN
IF INSERTING THEN
SELECT COUNT(mon_oficial)
INTO v_count
FROM monedas
WHERE mon_oficial = 'Y';
IF v_count = 1 THEN
RAISE_APPLICATION_ERROR(
-20010, 'Only one record can be set as 'Y'');
END IF;
END IF;
IF UPDATING THEN
SELECT COUNT(:OLD.mon_oficial)
INTO v_count
FROM monedas
WHERE :OLD.mon_oficial = 'Y';
IF v_count = 1 AND :NEW.mon_oficial = 'Y' THEN
RAISE_APPLICATION_ERROR(
-20010, 'Only one record can be set as 'Y'');
END IF;
END IF;
END mon_oficial_ins_trg;
/
SHOW ERRORS;
发布于 2017-06-30 13:24:50
在你代码中有两个错误
第一
SELECT COUNT(:OLD.mon_oficial)
INTO v_count
FROM monedas
WHERE :OLD.mon_oficial = 'Y';
部分,有关mutanting error的更多信息,请阅读本文
第二个错误,你有一个不正确的逻辑
IF v_count = 1 AND :NEW.mon_oficial = 'Y' THEN
部件,因为它可以是我们的当前行
试试看
CREATE OR REPLACE TRIGGER mon_oficial_ins_trg
BEFORE
INSERT OR UPDATE
ON monedas
FOR EACH ROW
DECLARE
v_count NUMBER(8);
BEGIN
IF INSERTING THEN
SELECT COUNT(mon_oficial)
INTO v_count
FROM monedas
WHERE mon_oficial = 'Y';
IF v_count = 1 THEN
RAISE_APPLICATION_ERROR(
-20010, 'Only one record can be set as 'Y'');
END IF;
END IF;
IF UPDATING THEN
IF :NEW.mon_oficial = 'Y' then
for m in (SELECT *
FROM monedas
WHERE mon_oficial = 'Y'
and rownum=1) loop
IF :NEW.mon_id <> m.mon_id THEN
RAISE_APPLICATION_ERROR(
-20010, 'Only one record can be set as 'Y'');
END IF;
END IF;
end loop;
END IF;
END mon_oficial_ins_trg;
/
SHOW ERRORS;
发布于 2019-07-23 05:44:32
这可以通过AFTER INSERT或UPDATE语句触发器非常简单地完成。相同的逻辑适用于这两个操作。
SELECT COUNT(*) INTO v_count FROM MONEDAS WHERE MON_OFICIAL = 'Y';
如果v_count >1,则RAISE_APPLICATION_ERROR...
这种方法的另一个优点是:它允许语句
UPDATE MONEDAS SET MON_OFICIAL = CASE MON_ID WHEN 'A‘THEN 'Y’ELSE 'N‘END;
如果在以前的官方货币更新为N之前将MON_ID = 'A‘的行更新为Y,则行级触发器可能会引发错误。
发布于 2020-04-30 21:19:23
我认为这个问题最好用约束来解决,而不是触发器。我不是这个答案的作者,但我认为它在这里是相关的。在其余的答案中有一个博客文章的链接,该文章建议避免触发器,但该链接似乎不起作用。
答案在这里:https://stackoverflow.com/a/182427
以下是@tony-andrews在该答案中提供的示例:
create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);
https://stackoverflow.com/questions/44837574
复制相似问题