3

在阻止插入唯一 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

4

3 回答 3

4

好吧,我想我明白发生了什么。您的问题的答案绝对是肯定的。如果禁用此触发器,可能会产生很大影响。

此触发器似乎存在的原因是为了处理插入表时提供主键值的情况。如果这发生在您的代码中的任何地方,他们删除触发器将破坏这些插入。

你必须做两件事。

  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. 弄清楚这是否真的发生。如果您确实插入没有主键的记录,您需要找出发生这种情况的原因以及行为是否正确。如果是你被触发器卡住了,否则修复它。如果您从不插入没有主键的记录,那么您可以禁用触发器。

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

于 2013-05-05T20:34:59.840 回答
1

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

除非这是一些被遗忘的实验,否则应用程序代码很可能取决于此触发器/序列。

对于自动增量功能,这是一个可接受的解决方案。请参阅:如何在 Oracle 上使用 AUTO_INCREMENT 创建 id?

于 2013-05-05T20:04:23.567 回答
1

“在这种情况下,主键用于唯一字符串。我无法想象自动增量在这种情况下完全有用。”

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

对我来说,担心的是 IF 声明。它表明有时密钥由应用程序填充,而有时它由数据库默认。那是乱七八糟的。除此之外,拥有两个键源意味着不再保证序列是唯一的。您现在有可能生成的序列nextval将与先前手动分配的编号发生冲突。

该怎么办?

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

于 2013-05-06T06:32:52.660 回答