使用第一个触发器PL \ SQL的值在第二个触发器上插入值

时间:2018-03-27 08:43:05

标签: sql oracle plsql

嗨我尝试在第二个触发器中插入值,只有在条件满足时才会使用第一个触发器的新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')

任何想法如何解决?

2 个答案:

答案 0 :(得分:2)

您不应该在同一个表中插入新记录,您应该修改您已经插入的行的列值 - 触发器触发的行。你得到的错误是因为第二个插入 - 只有 指定了URL值,而不是主题或ID(虽然第一个触发器会再次触发并设置该新行的ID - 所以它抱怨这个主题。)

在旧版本的Oracle中,在同一个触发点上有两个触发器可能很难,因为它们触发的顺序无法保证 - 例如,您的第二个触发器可能会在第一个触发器之前触发,而ID尚未设置。您可以使用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;
/

现在在第一次触发后触发,因此设置了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;
/