Oracle:自动增量触发器。

时间:2013-05-05 20:02:27

标签: oracle triggers autonumber

在数据库中找到以下触发器,该数据库阻塞了对唯一varchar主键的插入

CREATE OR REPLACE TRIGGER  "BI_PRIVILEGE" 
  before insert on "PRIVILEGE"               
  for each row  
begin   
  if :NEW."PRIVILEGE-ID" is null then 
    select "PRIVILEGE_SEQ".nextval into :NEW."PRIVILEGE-ID" from dual; 
  end if; 
end; 

这是一个自动数字生成器吗?我可以很容易地禁用它来解决我的问题,但是对于主键是否会有不可预知的负面冲突?

我实际上一直在寻找代码来为主键设置自动增量触发器,如果​​这是它正在做的事情,可以使用它作为模板。如果是,它可能会错误地执行,因为主键具体是PRIVILEGE_ID而不是PRIVILEGE-ID,在冲突的情况下,是否应该出现某种application_error

3 个答案:

答案 0 :(得分:4)

好的,我想我得到了正在发生的事情。您的问题的答案是绝对大量的。如果禁用此触发器,可能会产生很大的影响。

此触发器似乎存在的原因是处理在表中插入时提供主键值而不是的情况。如果在代码中出现 where ,则删除触发器会破坏这些插入。

你必须做两件事。

  1. 纠正扳机,它明显坏了;解决它:

    CREATE OR REPLACE TRIGGER  BI_PRIVILEGE
      before insert on PRIVILEGE              
      for each row  
    begin   
      if :NEW.PRIVILEGE_ID is null then 
        select PRIVILEGE_SEQ.nextval into :NEW.PRIVILEGE_ID from dual; 
      end if; 
    end; 
    

    如果您使用的是Oracle 11G或更高版本,则可以使用此代码:

      if :NEW.PRIVILEGE_ID is null then 
        :NEW.PRIVILEGE_ID := PRIVILEGE_SEQ.nextval; 
      end if; 
    
  2. 确定这是否真的发生了。如果您确实插入了没有主键的记录,则需要找出发生这种情况的原因以及行为是否正确。如果它是你的触发器,否则解决它。如果您从未插入没有主键的记录,则可以禁用触发器。

    找出最快的方法可能是禁用触发器,但它会破坏你的插入。如果这只是一个生产数据库,您可以判断它是否值得。我个人不会。

答案 1 :(得分:1)

此脚本将从序列中获取值并将其放入表中新插入的行中。它的行为与自动编号非常相似。我假设应用程序代码依赖于此触发器来填充插入行的主键,我不建议在评估应用程序的源代码之前将其删除。

除非有人忘记了实验,否则应用程序代码可能依赖于此触发器/序列。

这是自动增量功能的可接受解决方案。请参阅:How to create id with AUTO_INCREMENT on Oracle?

答案 2 :(得分:1)

  

“在这种情况下,主键是用于唯一的字符串。我不能   想象一下,自动增量在这方面可能完全有用   上下文。 “

如果您的意思是“PRIVILEGE-ID”是varchar2列,那么您就是正确的。一方面,数字也可以是一个字符串,因此它可以作为一个键。但是如果密钥应该具有特定格式的字母和数字,则单调递增的数字将不适合该模式。

对我而言,关注的是IF声明。它表明有时候密钥是由应用程序填充的,有时它是由数据库默认的。那太乱了。除了其他任何东西,拥有两个密钥源意味着序列不再保证是唯一的。现在,您生成的序列nextval可能会与之前手动分配的数字冲突。

怎么办?

如果您的开发环境具有良好的自动化单元或集成测试覆盖率,答案很简单:禁用触发器,运行测试套件并查看失败的原因。如果这没有描述您的设置(我感觉它没有),那么禁用该触发器的风险更大,因为您无法确信已经测试了可能填充表的所有路径。