2013-12-17 4 views
0

Я пытаюсь получить этот код сортируется, и он компилируется, но когда я проверить, удалив запись, если дает: Недопустимый идентификаторOracle триггер не работает

ошибка, вероятно, в: старый часть, но я просто не могу понять.

Это мой код.

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; 
+1

Есть ли причина, по которой вам нужно использовать динамический SQL в вашем триггере? Здесь, похоже, это не обязательно. Но, возможно, вы упростили проблему, чтобы опубликовать здесь, и в вашем фактическом коде есть некоторая причина, по которой вам нужен динамический SQL. –

+0

Можете ли вы показать нам структуру таблицы для 'Categorie' и' MailAbonnee'? – Drumbeg

+0

У вас есть «создать или заменить триггер t_OnDeleteCategory» дважды в начале –

ответ

2

Как @JustinCave предлагает, у вас есть проблема с динамическим SQL. v_categorienaam - переменная, но она находится в строке вашего SQL. Удалите динамический SQL, и ваша проблема исчезнет.

Кроме того, вы можете упростить код много, используя курсор для цикла, что-то вроде:

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; 
+0

Кроме того, вы можете удалить шаги 2 и 3, сделав внешние ключи базы данных 'on delete cascade' и' on delete set null' соответственно. –

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; 

Что проще форматировать и читать, и может быть подтверждено во время синтаксического анализа/компиляции, а не давать вам какие-либо возможные ошибки во время выполнения. Версия Колина еще проще; вы ничего не получаете от явной выборки.

Смежные вопросы