1

我有以下触发器,它在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;
/
4

2 回答 2

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 );

但是,这在多个会话可能同时插入同一行的多用户环境中是行不通的。

于 2012-06-12T19:44:07.180 回答
1

您可以将您的更改insert为以下内容,以检查是否已存在重复项。select 假定主键my_histidand 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;
于 2012-06-12T19:47:07.597 回答