我有以下触发器,当updated
变为Y
时会触发。我想仅在my_hist
表中不存在值时才插入旧值。如果存在相同的记录,则不应插入。最好的方法是创建一个约束来检查my_hist
表中的唯一性,还是在触发器中检查这个条件?如果是这样我怎么能在触发器中这样做?
或者是否可以在触发器中检查my_hist表的唯一约束,以便它不会插入重复的记录。
CREATE OR REPLACE TRIGGER mytrig
AFTER UPDATE
ON mytab
FOR EACH ROW
WHEN (
new.updated = 'Y'
)
BEGIN
INSERT INTO my_hist
VALUES (
:old.id,
:old.no,
:old.start_date,
:old.end_date,
SYSDATE
);
END mytrig;
/
答案 0 :(得分:3)
如果要强制实施唯一性,请使用唯一约束。这总是更适合自己编码。
您可以检查该行是否已作为INSERT
声明
INSERT INTO my_hist( id,
no,
start_date,
end_date,
some_other_column )
SELECT :old.id,
:old.no,
:old.start_date,
:old.end_date,
sysdate
FROM dual
WHERE NOT EXISTS( SELECT 1
FROM my_hist
WHERE my_hist.id = :old.id
AND my_hist.no = :old.no
AND my_hist.start_date = :old.start_date
AND my_hist.end_date = :old.end_date );
但是,在多用户环境中,多个会话可能同时插入同一行时,这将不起作用。
答案 1 :(得分:1)
您可以将insert
更改为以下内容,以检查是否已存在重复项。 select假定my_hist
的主键为id
和start_date
,请将where not exists
子句更改为仅使用主键值(如果它们不同)。
insert into my_hist
select :old.id, :old.no, :old.start_date, :old.end_date, sysdate
from dual
where not exists ( select 1
from my_hist
where id = :old.id
and start_date = :old.start_date
)
但是,这需要进行索引扫描,因此不是最佳选择。
而是引发异常。它明确命名为:dup_val_on_index
。如果确实如此,那么就忽略它。
BEGIN
INSERT INTO my_hist
VALUES (
:old.id,
:old.no,
:old.start_date,
:old.end_date,
SYSDATE
);
-- ignore an exception that get's raised if a duplicate value
-- gets inserted.
EXCEPTION WHEN DUP_VAL_ON_INDEX then null;
END mytrig;