在oracle中创建触发器以在插入cmd之前防止重复密钥

在oracle中创建触发器以在插入cmd之前防止重复密钥,oracle,triggers,primary-key,sql-insert,Oracle,Triggers,Primary Key,Sql Insert,我试图在oracle中创建一个触发器,该触发器将检测到重复的插入主键,并通过添加前缀字符(例如“p_”)来重命名新键。 如果有人知道这个问题的优雅解决方案,我会很高兴看到答案:) 我开始这样写smth: 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 = :n

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

我开始这样写smth:

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;

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

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

理论上你也可以做以下事情,但这真的不是一个好主意:

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;

对于clearification:如果您的密钥只有多个实例,则只会在密钥中附加多个“p”。光标仅适用于select语句返回零行或多行的情况。

您将得到一个未找到数据的异常,而不是一个空值;但我认为,如果尝试从插入到的表中进行选择,也会出现变异表错误。(我不确定PK是否会在触发之前报告约束冲突,我可能会尝试测试)。TBH我没有检查查询的功能,因为我有点期待一个有效的解决方案。我以为阿塔曼只是在寻求一些改进。你说得对,那样不行。我将删除我答案的这一部分。但是我不认为你会得到一个变异表错误,因为你没有插入到表中,只是调整了将要插入的值。不过不确定。谢谢:)。我知道使用自动递增序列作为主键可能是一个很好的解决方案。如果您已经有
id=200
id=p_200
的记录,并且试图插入一个
id=200
的新记录,您会怎么做?我已经考虑过这个问题,我只是想让smth变得简单,没有考虑到这一点,这是一项大学作业,所以我在实施上有限制。