【问题标题】:Creating trigger in oracle for preventing duplicate keys before inserting cmd在插入 cmd 之前在 oracle 中创建触发器以防止重复键
【发布时间】:2013-12-26 16:58:56
【问题描述】:

我正在尝试在 oracle 中创建一个触发器,该触发器将检测重复的插入主键,并通过添加前缀字符(例如“P_”)重命名新键。 如果有人知道这个问题的优雅解决方案,我会很高兴看到答案:)。

我开始这样写:

create or replace 
TRIGGER t1_trigger
BEFORE INSERT
ON T1
DECLARE selected_id varchar2(10);
BEGIN
  SELECT id INTO selected_id FROM T1 WHERE id = :new.id;
  IF (selected_id NOT NULL)
  THEN INSERT INTO T1 VALUES('p_');
  END IF;
END;

【问题讨论】:

  • 如果您已经有了id = 200id = p_200 的记录,并试图插入一条带有id=200 的新记录,您会怎么做?
  • 我已经考虑过这个问题,我只是想把事情简单化,没有考虑到这一点,这是一个大学作业,所以我在实施上有一个限制。

标签: oracle triggers primary-key sql-insert


【解决方案1】:

优雅的方法是使用自动递增序列作为主键。更多信息请查看herehere

另一种方法是使用MERGE-语句。这样您可以检查是否存在重复键,如果存在,请将旧键重命名为其他名称或相应地调整您插入的键。

理论上您也可以执行以下操作,但这确实不是一个好主意:

create or replace 
TRIGGER t1_trigger
BEFORE INSERT
ON T1
FOR EACH ROW
DECLARE 
cursor c1 is select id from t1 where id = :new.id;
BEGIN
  for i in c1 loop
        :new.id := 'p_' || :new.id;
    end loop;
END;

明确说明:如果您的密钥已经有多个实例,您只会在密钥上附加多个“p_”。光标仅适用于您的 select 语句将返回零或多于 1 行的情况。

【讨论】:

  • 你会得到一个 no-data-found 异常而不是空值;但我认为你也会因为尝试从插入的表中选择而得到一个变异表错误。 (我不确定 PK 是否会在触发器触发之前报告约束违规,我可能会尝试测试)。
  • TBH 我没有检查查询的功能,因为我有点期待一个可行的解决方案。我以为 Ataman 只是在寻找一些改进。你是对的,那样做是行不通的。我将删除我的答案的那部分。但我不认为你会得到一个变异表错误,因为你没有插入到表中,而只是调整将插入的值。不过不确定。
  • 谢谢:)。我知道这可能是使用自动递增序列作为主键的一个很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2014-09-19
  • 2011-05-14
  • 2021-09-29
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
相关资源
最近更新 更多