我试图声明一个变量,然后再次访问它以为特定ID更新同一张表。(将STATUS
从'E'
更新为'R'
)
create or replace trigger resume_trgr
before update on temp_jobs
DECLARE
job_status varchar(2);
begin
select STATUS into :job_status from temp_jobs where id=6120;
if :job_status='E'
then
update temp_jobs set STATUS='R' where id=6120;
end if;
end;
/
但是在执行上述代码时返回错误。错误代码如下:
已触发触发器resume_trgr
Errors: check compiler log
Error(5,27): PLS-00049: bad bind variable 'STATUS'
答案 0 :(得分:1)
您遇到的错误是……很好,很奇怪。一些评论:
STATUS
。into :job_status
而是into job_status
)。VARCHAR2
数据类型,而不是VARCHAR
。FOR EACH ROW
),并且在修复所有问题后,会遇到变异表错误 您可能会做的是:首先,测试用例:
SQL> create table temp_jobs
2 (id number,
3 status varchar2(10));
Table created.
SQL> insert into temp_jobs values (1, 'E');
1 row created.
SQL> insert into temp_jobs values (6120, 'E');
1 row created.
SQL> select * from temp_jobs;
ID STATUS
---------- ----------
1 E
6120 E
触发:请注意您和我的代码之间的区别。
SQL> create or replace trigger resume_trgr
2 before update on temp_jobs
3 for each row
4 DECLARE
5 JOB_STATUS VARCHAR2(2);
6 begin
7 :new.status := case when :old.status = 'E' then 'R'
8 else :new.status
9 end;
10 end;
11 /
Trigger created.
测试:
SQL> update temp_jobs set status = 'Y' where id = 6120;
1 row updated.
SQL> select * from temp_jobs;
ID STATUS
---------- ----------
1 E
6120 R
SQL> update temp_jobs set status = 'Y' where id = 6120;
1 row updated.
SQL> select * from temp_jobs;
ID STATUS
---------- ----------
1 E
6120 Y
SQL>
答案 1 :(得分:1)
在一个问题中,您说错误涉及STATUS
,但与您发布的代码不匹配。您应该遇到两个错误,涉及JOB_STATUS
。
那是因为它被定义为局部变量,并且您试图将其称为绑定变量。它不应该带有冒号前缀;这样可以编译:
create or replace trigger resume_trgr
before update on temp_jobs
declare
job_status temp_jobs.status%type;
begin
select STATUS into job_status from temp_jobs where id=6120;
if job_status='E'
then
update temp_jobs set STATUS='R' where id=6120;
end if;
end;
/
这样做,它会完全跳过变量:
create or replace trigger resume_trgr
before update on temp_jobs
begin
update temp_jobs set STATUS='R' where id=6120 and status = 'E';
end;
/
在触发器内执行的操作是有用,有效还是明智的事情是另一回事。似乎是一个单独的更新,您应该在“真实”更新之前手动进行,可能要在一个过程中进行-如果您确实要始终更新该特定ID的行,而不管您在“真实”中实际进行的其他操作(触发)更新。
如果您真正想做的是确保即使调用者没有明确地将状态更改为R
,那么您可能想要一个行级触发器来设置伪行值,而不是而不是具有硬编码ID的语句级触发器。