简体   繁体   English

在插入之前,同一表上的触发器不会更新列值

[英]Trigger on same table does not update the column value on before insert

Below is the trigger that am using to generate the value of EMP_ID by concatinating EMP_KEY with some text ,let say the EMP_KEY =2000 and TYPE_ID=1 then depending on the condition ,the value of EMP_ID should be CON2000 and so on. 下面是通过将EMP_KEY EMP_KEY为一些文本来生成EMP_ID值的触发器,假设EMP_KEY =2000TYPE_ID=1然后根据条件,EMP_ID的值应为CON2000,依此类推。 But when a record is inserted,the value of EMP_ID is generated just 'CON' and while a record is updated ,its working properly ie EMP_ID=CON2000 . 但是,当插入一条记录时, EMP_ID的值仅生成为“ CON”,而在更新一条记录时,它可以正常工作,即EMP_ID=CON2000

In this case, EMP_KEY is an autogenerated field and its NOT NULL 在这种情况下, EMP_KEY是一个自动生成的字段,其NOT NULL

What mistake am i making?Can someone please help? 我犯了什么错误?有人可以帮忙吗? I tiried with AFTER and using reference OLD as old and NEW as new,but no luck. 我和AFTER并用,使用OLD作为新的旧和NEW作为新的,但没有运气。

CREATE OR REPLACE TRIGGER EMP_ID_TRIGG BEFORE
INSERT OR UPDATE ON EMP 
FOR EACH ROW 
BEGIN 
IF :NEW.TYPE_ID = 1 THEN :NEW.EMP_ID := CONCAT('CON', :NEW.EMP_KEY);
ELSIF :NEW.TYPE_ID = 2 THEN :NEW.EMP_ID := CONCAT('SUBCON', 
:NEW.EMP_KEY);
ELSIF :NEW.TYPE_ID = 3 THEN :NEW.EMP_ID := CONCAT('JV', :NEW.EMP_KEY);
ELSE :NEW.EMP_ID := :NEW.EMP_KEY;
END IF;
END;

It sounds like you have two triggers on the table, one to generate the key (presumably from a sequence), then the one you have shown to use that key value to generate the ID. 听起来您在表上有两个触发器,一个触发器生成密钥(可能是从一个序列生成的),然后是一个显示的要使用该密钥值生成ID的触发器。 Simple demo: 简单的演示:

create table emp (emp_key number primary key,
  type_id number,
  emp_id varchar2(20),
  emp_name varchar2(20)
);

create sequence emp_key_seq;

create or replace trigger emp_key_trigg
before insert on emp
for each row 
begin 
  :new.emp_key := emp_key_seq.nextval;
end;
/

create or replace trigger emp_id_trigg
before insert or update on emp 
for each row 
begin 
  if :new.type_id = 1 then
    :new.emp_id := concat('CON', :new.emp_key);
  elsif :new.type_id = 2 then
    :new.emp_id := concat('SUBCON', :new.emp_key);
  elsif :new.type_id = 3 then
    :new.emp_id := concat('JV', :new.emp_key);
  else
    :new.emp_id := :new.emp_key;
  end if;
end;
/

then inserting and updating does what you describe: 然后插入和更新执行您所描述的操作:

insert into emp (type_id, emp_name) values (1, 'Jane');
insert into emp (type_id, emp_name) values (2, 'Joe');

select * from emp;

   EMP_KEY    TYPE_ID EMP_ID               EMP_NAME            
---------- ---------- -------------------- --------------------
         1          1 CON                  Jane                
         2          2 SUBCON               Joe                 

update emp set emp_name = 'Jen' where emp_name = 'Jane';

select * from emp;

   EMP_KEY    TYPE_ID EMP_ID               EMP_NAME            
---------- ---------- -------------------- --------------------
         1          1 CON1                 Jen                 
         2          2 SUBCON               Joe                 

From 11g you can control the order that triggers with the same timing point fire with the FOLLOWS clause , so in this case ad follow emp_key_trigg (with the name of your actual trigger, of course): 从11g开始,您可以使用FOLLOWS子句控制以相同的时间点触发的触发器的顺序,因此在这种情况下,广告应follow emp_key_trigg (当然,使用实际触发器的名称):

create or replace trigger emp_id_trigg
before insert or update on emp 
for each row
follows emp_key_trigg
begin 
  if :new.type_id = 1 then
    :new.emp_id := concat('CON', :new.emp_key);
  elsif :new.type_id = 2 then
    :new.emp_id := concat('SUBCON', :new.emp_key);
  elsif :new.type_id = 3 then
    :new.emp_id := concat('JV', :new.emp_key);
  else
    :new.emp_id := :new.emp_key;
  end if;
end;
/

insert into emp (type_id, emp_name) values (1, 'Jane');
insert into emp (type_id, emp_name) values (2, 'Joe');

select * from emp;

   EMP_KEY    TYPE_ID EMP_ID               EMP_NAME            
---------- ---------- -------------------- --------------------
         3          1 CON3                 Jane                
         4          2 SUBCON4              Joe                 

You could also combine the two triggers into one (which you'd have to do on earlier releases anyway, as triggers of the same type for the same statement are not guaranteed to fire in any specific order ): 您还可以将这两个触发器组合为一个(无论如何,您都必须在较早的发行版中进行此操作,因为对于同一条语句,相同类型的触发器不能保证以任何特定的顺序触发 ):

-- don't do this unless you're sure it's what you have to do!
drop trigger emp_key_trigg;

create or replace trigger emp_id_trigg
before insert or update on emp 
for each row 
begin 
  if inserting then
    :new.emp_key := emp_key_seq.nextval;
  end if;

  if :new.type_id = 1 then
    :new.emp_id := concat('CON', :new.emp_key);
  elsif :new.type_id = 2 then
    :new.emp_id := concat('SUBCON', :new.emp_key);
  elsif :new.type_id = 3 then
    :new.emp_id := concat('JV', :new.emp_key);
  else
    :new.emp_id := :new.emp_key;
  end if;
end;
/

insert into emp (type_id, emp_name) values (1, 'Jane');
insert into emp (type_id, emp_name) values (2, 'Joe');

select * from emp;

   EMP_KEY    TYPE_ID EMP_ID               EMP_NAME            
---------- ---------- -------------------- --------------------
         5          1 CON5                 Jane                
         6          2 SUBCON6              Joe                 

Works OK for me on 11gR2: 我可以在11gR2上正常工作:

SQL> CREATE TABLE test
  2  (
  3     type_id   NUMBER,
  4     emp_id    VARCHAR2 (20),
  5     emp_key   VARCHAR2 (20)
  6  );

Table created.

SQL> CREATE OR REPLACE TRIGGER EMP_ID_TRIGG
  2     BEFORE INSERT OR UPDATE
  3     ON test
  4     FOR EACH ROW
  5  BEGIN
  6     IF :NEW.TYPE_ID = 1
  7     THEN
  8        :NEW.EMP_ID := CONCAT ('CON', :NEW.EMP_KEY);
  9     ELSIF :NEW.TYPE_ID = 2
 10     THEN
 11        :NEW.EMP_ID := CONCAT ('SUBCON', :NEW.EMP_KEY);
 12     ELSIF :NEW.TYPE_ID = 3
 13     THEN
 14        :NEW.EMP_ID := CONCAT ('JV', :NEW.EMP_KEY);
 15     ELSE
 16        :NEW.EMP_ID := :NEW.EMP_KEY;
 17     END IF;
 18  END;
 19  /

Trigger created.

SQL>

Testing: 测试:

SQL> INSERT INTO test (type_id, emp_key) VALUES (1, 'X');

1 row created.

SQL> SELECT * FROM test;

   TYPE_ID EMP_ID               EMP_KEY
---------- -------------------- --------------------
         1 CONX                 X

SQL> UPDATE test SET type_id = 2;

1 row updated.

SQL> SELECT * FROM test;

   TYPE_ID EMP_ID               EMP_KEY
---------- -------------------- --------------------
         2 SUBCONX              X

SQL>

Are you sure EMP_KEY is not NULL while inserting? 您确定插入时EMP_KEY不为NULL吗? That might cause what you're saying. 这可能会导致您在说什么。

Otherwise, do edit your question and copy/paste SQL*Plus session so that we could see what you did and how Oracle responded. 否则,请编辑您的问题并复制/粘贴SQL * Plus会话,以便我们可以看到您的操作以及Oracle的响应方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM