存档触发问题

时间:2019-04-20 13:42:06

标签: sql oracle triggers

试图创建一个触发器,当名为COMPLETION_STATUS的列从不完整变为完整时,dbms是插入的占位符,但是在if语句中出现以下错误

  

错误(6,1):PLS-00103:在预期以下情况之一时,遇到符号在此处输入代码“ SELECT”的情况:begin函数pragma过程子类型类型当前游标已删除先于符号用“ begin”代替了“ SELECT”继续。

     

错误(9,1):PLS-00103:预期以下情况之一时遇到符号“ IF”:*&-+; /在mod余数rem和/或具有相交的负序的组中,在连接||处开始并集multiset符号“;”被替换为“ IF”继续。

     

错误(13,4):PLS-00103:在预期以下情况之一时遇到符号“文件结束” :(如果loop mod null编译指示提高返回选择更新,则开始情况声明goto的异常退出与<<继续关闭当前删除删除获取锁插入打开回滚保存点集sql执行提交所有合并管道清除

代码:

create or replace TRIGGER ARCHIVING_TRIG 
BEFORE UPDATE OF COMPLETION_STATUS ON PROJECT_DATA

BEGIN
DECLARE COMPLETION_STATUS1 VARCHAR2(9);
SELECT COMPLETION_STATUS into COMPLETION_STATUS1
FROM PROJECT_DATA WHERE COMPLETION_STATUS = 'complete'

IF COMPLETION_STATUS1 = 'complete'
THEN 
DBMS.output('123');
END IF;
END;

2 个答案:

答案 0 :(得分:1)

  • DECLARE块应该在BEGIN块之前。
  • SELECT ...语句需要用分号(;)终止。
  • dbms_output.put_line()而不是dbms.output();
  • 您正在尝试分配查询结果,该查询结果可能会向标量变量返回多个行。
  • project_data中选择的行与触发触发器的行无关。

我建议您使用类似的东西:

CREATE TRIGGER archiving_trig
               AFTER UPDATE
                     ON project_data
               FOR EACH ROW
               WHEN (old.completion_status <> 'complete'
                     AND new.completion_status = 'complete')
BEGIN
  dbms_output.put_line('Trigger fired for ID ' || :new.id);
END;

db<>fiddle

  • 我认为也许AFTER是更好的时间,因为您想在状态成功更改后将行存档。
  • 由于WHEN,仅当completion_status'complete'以外的其他内容更改为'complete'时,触发器才会触发。但是,当状态从'complete'变为其他状态时,您可能还需要一种从归档中删除条目的方法。在这里没有涵盖。
  • 将其声明为FOR EACH ROW,让您通过:new访问更新后的行的值。这样一来,您无需查询即可选择该内容,也无需选择变量。

答案 1 :(得分:0)

我想你需要这个:

create table PROJECT_DATA_NEW as select * from PROJECT_DATA where 1=2;


CREATE OR REPLACE TRIGGER ARCHIVING_TRIG 
AFTER UPDATE
   ON PROJECT_DATA
   FOR EACH ROW

DECLARE
status number;
BEGIN
status:=0;
select 1 into status from PROJECT_DATA where 
:new.COMPLETION_STATUS='complete' and 
:old.COMPLETION_STATUS='incomplete'

if (status=1) then
insert into PROJECT_DATA_NEW values(:old.column1,
:old.column2,
:old.column3,
:old.column4,
:old.column5,....etc); 
end if;
END;

/