简体   繁体   English

在第二个触发器上插入值,并从第一个触发器PL \\ SQL中插入值

[英]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.

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