试图创建一个触发器,当名为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;
答案 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;
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;
/