[英]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 =2000
和TYPE_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.