在复合触发器中声明游标 pl/sql
declaring cursor in compound trigger pl/sql
当我运行这段代码时,我得到了这个错误:
PLS-00103:在期望以下之一时遇到符号 "IS":
:= . ( @ % ; not null range default character.
我认为声明部分有问题,但相同的声明在 row-lvl 触发器中有效,所以我很困惑在复合触发器中是否允许这样做。我找不到例子,所以我在这里问你。
create or replace trigger ivan_moving
for update of country on clients
compound trigger
declare
n_country clients.country%type;
min_date clients.bday%type;
cursor ivans is select* from clients where fname like 'Ivan%' and Bday > (select min(Bday) from clients where fname like 'Ivan%');
client_ivan ivans%rowtype;
before statement is
min_date = select Bday from clients where fname like 'Ivan%' and Bday = (select min(Bday) from clients where fname like 'Ivan%');
end before statement;
after each row is
begin
if :OLD.country <> :NEW.country and fname = 'Ivan%' and bday = min_date
n_country := :new.country;
end if;
end after each row;
after statement is
begin
open ivans;
loop
fetch ivans into client_ivan;
exit when ivans%notfound;
update clients set country = n_country where id = client_ivan.id;
end loop;
close ivans;
end after statement;
end ivan_moving;
/
不少错误,例如
- 你不应该使用
declare
- 在 PL/SQL 中,
SELECT
需要 INTO
- 不是
= 'Ivan%'
而是like 'Ivan%'
- 您似乎"forgot" 为某些列指定了
:new
可能还有其他一些我没有提到的错误。我不知道触发器是否按照您的预期执行,但是 - 至少语法错误现在已修复。
SQL> create or replace trigger ivan_moving
2 for update of country on clients
3 compound trigger
4 n_country clients.country%type;
5 min_date clients.bday%type;
6 cursor ivans is
7 select * from clients
8 where fname like 'Ivan%'
9 and bday > min_date;
10 client_ivan ivans%rowtype;
11
12 before statement is
13 begin
14 select bday
15 into min_date
16 from clients
17 where fname like 'Ivan%'
18 and bday = (select min(bday)
19 from clients
20 where fname like 'Ivan%');
21 end before statement;
22
23 after each row is
24 begin
25 if :old.country <> :new.country
26 and :new.fname like 'Ivan%'
27 and :new.bday = min_date
28 then
29 n_country := :new.country;
30 end if;
31 end after each row;
32
33 after statement is
34 begin
35 open ivans;
36 loop
37 fetch ivans into client_ivan;
38 exit when ivans%notfound;
39 update clients set country = n_country where id = client_ivan.id;
40 end loop;
41 close ivans;
42 end after statement;
43
44 end ivan_moving;
45 /
Trigger created.
当我运行这段代码时,我得到了这个错误:
PLS-00103:在期望以下之一时遇到符号 "IS":
:= . ( @ % ; not null range default character.
我认为声明部分有问题,但相同的声明在 row-lvl 触发器中有效,所以我很困惑在复合触发器中是否允许这样做。我找不到例子,所以我在这里问你。
create or replace trigger ivan_moving
for update of country on clients
compound trigger
declare
n_country clients.country%type;
min_date clients.bday%type;
cursor ivans is select* from clients where fname like 'Ivan%' and Bday > (select min(Bday) from clients where fname like 'Ivan%');
client_ivan ivans%rowtype;
before statement is
min_date = select Bday from clients where fname like 'Ivan%' and Bday = (select min(Bday) from clients where fname like 'Ivan%');
end before statement;
after each row is
begin
if :OLD.country <> :NEW.country and fname = 'Ivan%' and bday = min_date
n_country := :new.country;
end if;
end after each row;
after statement is
begin
open ivans;
loop
fetch ivans into client_ivan;
exit when ivans%notfound;
update clients set country = n_country where id = client_ivan.id;
end loop;
close ivans;
end after statement;
end ivan_moving;
/
不少错误,例如
- 你不应该使用
declare
- 在 PL/SQL 中,
SELECT
需要INTO
- 不是
= 'Ivan%'
而是like 'Ivan%'
- 您似乎"forgot" 为某些列指定了
:new
可能还有其他一些我没有提到的错误。我不知道触发器是否按照您的预期执行,但是 - 至少语法错误现在已修复。
SQL> create or replace trigger ivan_moving
2 for update of country on clients
3 compound trigger
4 n_country clients.country%type;
5 min_date clients.bday%type;
6 cursor ivans is
7 select * from clients
8 where fname like 'Ivan%'
9 and bday > min_date;
10 client_ivan ivans%rowtype;
11
12 before statement is
13 begin
14 select bday
15 into min_date
16 from clients
17 where fname like 'Ivan%'
18 and bday = (select min(bday)
19 from clients
20 where fname like 'Ivan%');
21 end before statement;
22
23 after each row is
24 begin
25 if :old.country <> :new.country
26 and :new.fname like 'Ivan%'
27 and :new.bday = min_date
28 then
29 n_country := :new.country;
30 end if;
31 end after each row;
32
33 after statement is
34 begin
35 open ivans;
36 loop
37 fetch ivans into client_ivan;
38 exit when ivans%notfound;
39 update clients set country = n_country where id = client_ivan.id;
40 end loop;
41 close ivans;
42 end after statement;
43
44 end ivan_moving;
45 /
Trigger created.