我正在尝试对此代码进行排序,并且它会进行编译,但是当我通过删除记录进行测试时,如果给出: 标识符无效
错误可能在:旧部分,但我无法理解。
这是我的代码。
create or replace trigger t_OnDeleteCategory
create or replace trigger t_OnDeleteCategory
before delete on Categorie
for each row
declare
v_textMail varchar2(2000);
v_emailAdres MailAbonnee.emailAdres%type;
v_Voornaam MailAbonnee.voornaam%type;
v_Achternaam MailAbonnee.Achternaam%type;
c_cursor SYS_REFCURSOR;
v_sql varchar2(2000);
v_categorienaam categorie.naam%type;
begin
v_categorienaam := :old.naam;
--1) mailbericht verzenden
v_sql := 'select voornaam, achternaam, emailAdres from MailAbonnee where id in (select mailAbonneeID from CategorieAbonnement where categorieNaam = v_categorienaam)';
open c_cursor for v_sql;
loop
fetch c_cursor into v_Voornaam, v_Achternaam, v_emailAdres;
exit when c_cursor%notfound;
v_textMail := 'Beste ' || v_Voornaam || ' ' || v_Achternaam || ', uw abonnement is opgeheven voor Categorie '|| v_categorienaam || '.';
sendMailAbonnee(v_textMail, v_emailadres);
end loop;
--2) verwijder alle abonnementen
delete from CategorieAbonnement where categorieNaam = v_categorienaam;
--3) pas alle nieuwsberichten aan
update Nieuwsbericht set categorieNaam = '' where categorieNaam = v_categorienaam;
end;
答案 0 :(得分:2)
就像@JustinCave建议的那样,你的动态SQL有问题。 v_categorienaam
是一个变量,但它在SQL的字符串中。删除动态SQL,您的问题就会消失。
此外,您可以使用游标for循环来简化代码,例如:
create or replace trigger t_OnDeleteCategory
before delete on Categorie
for each row
declare
v_textMail varchar2(2000);
begin
--1) mailbericht verzenden
for c in (
select voornaam, achternaam, emailAdres
from MailAbonnee
where id in (
select mailAbonneeID from CategorieAbonnement where categorieNaam = :old.naam
)
) loop
v_textMail := 'Beste ' || c.voornaam || ' ' || c.achternaam || ', uw abonnement is opgeheven voor Categorie '|| c.naam || '.';
sendMailAbonnee(v_textMail, c.emailadres);
end loop;
--2) verwijder alle abonnementen
delete from CategorieAbonnement where categorieNaam = :old.naam;
--3) pas alle nieuwsberichten aan
update Nieuwsbericht set categorieNaam = '' where categorieNaam = :old.naam;
end;
答案 1 :(得分:1)
在这一行:
v_sql := 'select voornaam, achternaam, emailAdres from MailAbonnee where id in (select mailAbonneeID from CategorieAbonnement where categorieNaam = v_categorienaam)';
....你指的是v_categorienaam
,但是当执行动态SQL时,这不是范围内的变量。您应该使用绑定变量:
v_sql := 'select voornaam, achternaam, emailAdres from MailAbonnee where id in (select mailAbonneeID from CategorieAbonnement where categorieNaam = :v_categorienaam)';
然后
open c_cursor for v_sql using v_categorienaam;
但正如其他人已经指出的那样,似乎没有任何理由让它变得充满活力。你可以摆脱v_sql
而只是做:
open c_cursor for
select voornaam, achternaam, emailAdres
from MailAbonnee
where id in (
select mailAbonneeID
from CategorieAbonnement
where categorieNaam = v_categorienaam;
哪种格式和读取更容易,并且可以在解析/编译时验证,而不是在运行时给您任何潜在的错误。科林的版本更简单;你没有从显式获取中获得任何东西。