[英]Insert value on second trigger with value from first trigger PL\SQL
Hi I try to Insert value in the second trigger with new id from first trigger only if condition is fulfiled, but I'm stuck. 嗨,我尝试仅在满足条件的情况下,才使用第一个触发器的新ID在第二个触发器中插入值,但是我被卡住了。
table1_trg
works table1_trg
工作
CREATE TABLE table1 (
id NUMBER(9,0) NOT NULL,
subject VARCHAR2(200) NOT NULL,
url_address VARCHAR2(200) NOT NULL,
)
CREATE OR REPLACE TRIGGER table1_trg
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
SELECT table1_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
CREATE OR REPLACE TRIGGER table1_url
BEFORE INSERT ON table1
FOR EACH ROW
WHEN (NEW.subject = 'Task')
BEGIN
INSERT INTO CSB.table1 (url_address)
VALUES ('blabla.com?' || :new.id);
END;
/
I insert only subject but after that i receive exception that subject
can not be null. 我只插入主题,但是在那之后我收到
subject
不能为null的异常。
INSERT INTO corp_tasks_spec (subject) VALUES ('Task')
Any ideas how to resolve it? 任何想法如何解决呢?
You should not be inserting a new record into the same table, you should be modifying the column values for the row you're already inserting - which the trigger is firing against. 您不应该在同一个表中插入新记录,而应该修改已经插入的行的列值-触发器将针对该值。 You're getting the error because of that second insert - which is only specifying the URL value, not the subject or ID (though the first trigger would fire again and set the ID for that new row as well - so it complains about the subject).
您由于第二个插入而收到错误- 仅插入URL值,而不指定主题或ID(尽管第一个触发器会再次触发并设置该新行的ID-因此它抱怨主题)。
Having two triggers on the same firing point can be difficult in old versions of Oracle as the order they fired wasn't guaranteed - so for instance your second trigger might fire before the first, and ID hasn't been set yet. 在旧版本的Oracle中,在同一触发点上具有两个触发器可能很困难,因为不能保证它们的触发顺序-例如,您的第二个触发器可能在第一个触发器之前触发,并且尚未设置ID。 You can control the order in later versions (from 11g) with
FOLLOWS
: 您可以使用
FOLLOWS
控制更高版本(从11g起)的顺序:
CREATE OR REPLACE TRIGGER table1_url
BEFORE INSERT ON table1
FOR EACH ROW
FOLLOWS table1_trg
WHEN (NEW.subject = 'Task')
BEGIN
:NEW.url_address := 'blabla.com?' || :new.id;
END;
/
This now fires after the first trigger, so ID is set, and assigns a value to the URL in this row rather than trying to create another row: 现在,这会在第一个触发器之后触发,因此设置了ID,并为该行中的URL分配了一个值,而不是尝试创建另一行:
INSERT INTO table1 (subject) VALUES ('Task');
1 row inserted.
SELECT * FROM table1;
ID SUBJECT URL_ADDRESS
---------- ---------- --------------------
2 Task blabla.com?2
But you don't really need two triggers here, you could do: 但是您实际上并不需要两个触发器,您可以这样做:
DROP TRIGGER table1_url;
CREATE OR REPLACE TRIGGER table1_trg
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
:NEW.id := table1_seq.NEXTVAL; -- no need to select from dual in recent versions
IF :NEW.subject = 'Task' THEN
:NEW.url_address := 'blabla.com?' || :new.id;
END IF;
END;
/
Then that trigger generates the ID and sets the URL: 然后,该触发器生成ID并设置URL:
INSERT INTO table1 (subject) VALUES ('Task');
1 row inserted.
SELECT * FROM table1;
ID SUBJECT URL_ADDRESS
---------- ---------- --------------------
2 Task blabla.com?2
3 Task blabla.com?3
Of course, for anything except Task you'll have to specify the URL as part of the insert, or it will error as that is a not-null column. 当然,对于除Task以外的任何内容,您都必须将URL指定为插入的一部分,否则将出错,因为那是非空列。
Create sequence 创建序列
CREATE SEQUENCE table1_SEQ
START WITH 1
MAXVALUE 100000
MINVALUE 1
NOCYCLE
NOCACHE
NOORDER;
CREATE TRIGGER 创建触发器
CREATE OR REPLACE TRIGGER table1_TRG
Before Insert
ON table1 Referencing New As New Old As Old
For Each Row
Declare V_Val Number;
Begin
Select table1_SEQ.NextVal into V_Val From Dual;
If Inserting Then
:New.id:= V_Val;
End If;
End;
/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.