Oracle: auto-increment trigger.

▼魔方 西西 提交于 2019-12-10 17:53:22

问题


Found the following trigger in a database which was blocking inserts on a unique varchar primary key

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; 

Is this an auto-number generator? I can easily disable it to fix my problem, but will there be unforseen negative ramifcations for the primary key?

I have actually been looking for code to set up auto-increment triggers for primary keys and could use this as a template if this is what it is doing. If it is, it is likely doing it incorrectly as the primary key is specifically PRIVILEGE_ID not PRIVILEGE-ID, also, shouldn't some sort of application_error arise in the case of conflicts, etc?


回答1:


Okay, I think I get what's going on. The answer to your question is an absolutely massive yes. There can be a large impact if you disable this trigger.

The reason this trigger seems to exist is to deal with the situation where a primary key value is not provided on an insert into your table. If this occurs anywhere in your code them removing the trigger will break those inserts.

You have to do two things.

  1. Correct the trigger, it's obviously broken; fix it:

    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; 
    

    If you're using Oracle 11G or greater then you can use this instead:

      if :NEW.PRIVILEGE_ID is null then 
        :NEW.PRIVILEGE_ID := PRIVILEGE_SEQ.nextval; 
      end if; 
    
  2. Work out whether this actually happens. If you do insert records without a primary key you need to find out why this happening and whether the behaviour is correct. If it is you're stuck with the trigger, otherwise fix that. If you never insert records without a primary key then you can disable the trigger.

    The quickest way of finding out may be to disable the trigger anyway but it would break your inserts. If this is a production database only you can tell whether it's worth it. I wouldn't personally.




回答2:


This script will get a value from a sequence and place it into a newly inserted row in the table. It is acting very similar to an autonumber. I assume that application code relies upon this trigger to populate the primary key for inserted rows, I would not recommend removing it before evaluating an application's source code.

Unless this was some forgotten about experiment, it is likely the application code depends on this trigger/sequence.

This is an acceptable solution for autoincrement functionality. See: How to create id with AUTO_INCREMENT on Oracle?




回答3:


" in this case the primary key is meant for unique strings. I cant imagine that auto-increment could be altogether useful in that context. "

If you mean that "PRIVILEGE-ID" is a varchar2 column then you're sort of correct. On the one hand, a number can also be a string, so it would work as a key. But if the key is supposed to have a specific format of letters and numbers, a monotonically incrementing number won't fit the patten.

For me, the concern would be that IF statement. It suggests that sometimes the key is populated by the application and at other times it is defaulted by the database. That is messy. Apart from anything else, having two sources of keys means that the sequence is no longer guaranteed to be unique. You now have the possibility that the sequence generated nextval will collide with a previous manually assigned number.

What to do?

If you have a development environment with good coverage from automated unit or integration tests, the answer is simple: disable the trigger, run your test suites and see what fails. If that doesn't describe your set-up (and I have the feeling it doesn't) then disabling the that trigger is riskier, because you can't have confidence that you have tested all the paths which might populate the table.



来源:https://stackoverflow.com/questions/16388576/oracle-auto-increment-trigger

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!