PL / SQL触发器问题(将数据从表1复制到表2)

时间:2015-10-27 14:02:49

标签: sql database oracle plsql triggers

我环顾四周,尝试了一些我读过的解决方案。我正在尝试创建一个pl / sql触发器,如果​​满足一个子句,它将数据从一个表复制到另一个表。我觉得我可能只是制造了一个愚蠢的语法错误,而不是一个完全的关键失败,但会感激一些帮助。

create or replace TRIGGER TRG_APPLICATIONS
BEFORE INSERT or UPDATE OF APP_ID, Status_id
ON APPLICATIONS
FOR EACH ROW
BEGIN

:new.APP_ID := SEQ_APP_ID.nextval;
:new.APP_DATE := SYSDATE;

IF STATUS_ID = 2 OR STATUS_ID = 5 OR STATUS_ID = 7 OR STATUS_ID = 8 THEN
INSERT INTO APP_HISTORY
SELECT SRN, STATUS_ID, APP_DATE
FROM APPLICATIONS;
END IF;

END;

这是错误

  

6 4 PLS-00201:标识符' STATUS_ID'必须声明

     

6 1 PL / SQL:忽略语句

3 个答案:

答案 0 :(得分:2)

一旦您注意到您需要使用以下值引用这些值:NEW以获取此插入或更新的ID的STATUS的当前值,您将会遇到第二个错误 - 您无法查询其中的表触发器存在,因为其内容不断变化。你会得到一个变异表错误。更不用说您在SELECT上没有where子句,因此您将所有APPLICATIONS转储到APP_HISTORY中。我打赌你想要的就是复制更新之前的行。当然插入前没有行,所以没有什么可以复制的。或者您想将新值复制到插入时的HISTORY表中吗?

假设您希望将旧值保留在更新中,那么您将:

create or replace TRIGGER TRG_APPLICATIONS
BEFORE INSERT or UPDATE OF APP_ID, Status_id
ON APPLICATIONS
FOR EACH ROW
BEGIN

-- APP_ID better not be the PK or it is changing on UPDATE! 
-- IF you only want this value set once on INSERT, wrap it in an IF INSERTING ... END IF; structure
:new.APP_ID := SEQ_APP_ID.nextval;
:new.APP_DATE := SYSDATE;

IF UPDATING AND ( :NEW.STATUS_ID = 2 OR :NEW.STATUS_ID = 5 OR :NEW.STATUS_ID = 7 OR :NEW.STATUS_ID = 8 )
THEN
   INSERT INTO APP_HISTORY (SRN, STATUS_ID, APP_DATE)
   VALUES (:OLD.SRN, :OLD.STATUS_ID, :OLD.APP_DATE);
END IF;

END;

关于你第一次触发触发器的其他想法 - 你的触发器在更新app_id时触发,但随后在触发器内再次更改app_id。因此,如果您的UI正在设置APP_ID值,然后使用该值插入相关记录 - 您只是搞砸了。

答案 1 :(得分:0)

可能您需要添加NEW

IF :NEW.STATUS_ID = 2 OR :NEW.STATUS_ID = 5 
OR :NEW.STATUS_ID = 7 OR :NEW.STATUS_ID = 8 THEN
    INSERT INTO APP_HISTORY (srn, status_id, app_date)
    VALUES (:NEW.SRN, :NEW.STATUS_ID, :NEW.APP_DATE);
END IF;

答案 2 :(得分:0)

检查出来:

create or replace TRIGGER TRG_APPLICATIONS
  BEFORE INSERT or UPDATE OF APP_ID, Status_id
  ON APPLICATIONS
  FOR EACH ROW
BEGIN

  :new.APP_ID := SEQ_APP_ID.nextval;
  :new.APP_DATE := SYSDATE;

  IF :new.STATUS_ID = 2 OR 
     :new.STATUS_ID = 5 OR 
     :new.STATUS_ID = 7 OR 
     :new.STATUS_ID = 8 THEN

    INSERT INTO APP_HISTORY (srn, status_id, app_date)
     values (:new.srn, :new.status_id, :new.app_date);

 END IF;

END;