Няколко въпроса без определен ред.
Първо, в тялото на тригер на ниво ред трябва да използвате :new
и :old
за справка с новите и старите записи. Водещото дебело черво е необходимо. Така че вашето WHERE
клауза трябва да бъде
WHERE PROJECTID = :new.PROJECTID
Второ, ако изпълнявате своя CREATE TRIGGER
в SQL*Plus можете да получите списък с грешки и предупреждения, като използвате SHOW ERRORS
команда, т.е.
SQL> show errors
Можете също така да направите заявка за DBA_ERRORS
таблица (или ALL_ERRORS
или USER_ERRORS
в зависимост от вашето ниво на привилегия), но това не е нещо, до което обикновено трябва да прибягвате.
Трето, ако приемем, че синтактичните грешки бъдат коригирани, ще получите мутиращ грешка в таблицата
ако използвате тази логика. Тригер на ниво ред на таблица A (TPM_TRAININGPLAN
в този случай) не може да направи запитване към таблица A, защото таблицата може да е в непоследователно състояние. Можете да заобиколите това, както Тим показва в статията си, като създадете пакет с колекция, инициализирате тази колекция в тригер преди израз, попълните данните в колекцията в тригер на ниво ред и след това обработите модифицираните редове в тригер след изявление. Това обаче е прилично количество сложност, което да добавите към системата, тъй като ще трябва да управлявате множество различни обекти.
Като цяло би било по-добре да внедрите тази логика като част от какъвто и да е API, който използвате за манипулиране на TPM_TRAININGPLAN
маса. Ако това е съхранена процедура, има много по-голям смисъл да поставите логиката за актуализиране на TPM_PROJECT
в тази съхранена процедура, вместо да я поставите в тригер. Известно е, че е болезнено да се опитвате да отстранявате грешки в приложение, което има много логика, вградена в тригери, защото това прави много трудно за разработчиците да следват точно какви операции се изпълняват. Като алтернатива можете да премахнете TRAININGDELIVERYSTART
колона от TPM_PROJECT
таблица и просто изчислете минималната начална дата по време на изпълнение.
Четвърто, ако вашият тригер се задейства при вмъквания, актуализации и изтривания, не можете просто да посочите :new
стойности. :new
е валиден за вмъквания и актуализации, но ще бъде NULL, ако правите изтриване. :old
е валиден за изтривания и актуализации, но ще бъде NULL, ако правите вмъкване. Това означава, че вероятно трябва да имате логика по линия на (позовавайки се на пакетното решение на Тим)
BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;