嗨我尝试在第二个触发器中插入值,只有在条件满足时才会使用第一个触发器的新id,但是我被卡住了。
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;
/
我只插入主题但在此之后我收到subject
不能为空的异常。
INSERT INTO corp_tasks_spec (subject) VALUES ('Task')
任何想法如何解决?
答案 0 :(得分:2)
您不应该在同一个表中插入新记录,您应该修改您已经插入的行的列值 - 触发器触发的行。你得到的错误是因为第二个插入 - 只有 指定了URL值,而不是主题或ID(虽然第一个触发器会再次触发并设置该新行的ID - 所以它抱怨这个主题。)
在旧版本的Oracle中,在同一个触发点上有两个触发器可能很难,因为它们触发的顺序无法保证 - 例如,您的第二个触发器可能会在第一个触发器之前触发,而ID尚未设置。您可以使用FOLLOWS
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;
/
现在在第一次触发后触发,因此设置了ID,并为此行中的URL分配值,而不是尝试创建另一行:
INSERT INTO table1 (subject) VALUES ('Task');
1 row inserted.
SELECT * FROM table1;
ID SUBJECT URL_ADDRESS
---------- ---------- --------------------
2 Task blabla.com?2
但你真的不需要两个触发器,你可以这样做:
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;
/
然后该触发器生成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
当然,对于除Task之外的任何内容,您必须将URL指定为插入的一部分,否则它将出错,因为它是非空列。
答案 1 :(得分:0)
创建序列
CREATE SEQUENCE table1_SEQ
START WITH 1
MAXVALUE 100000
MINVALUE 1
NOCYCLE
NOCACHE
NOORDER;
创建触发器
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;
/