Несколько проблем в произвольном порядке.
Во-первых, в теле триггера уровня строки необходимо использовать :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, поскольку таблица может находиться в несогласованном состоянии.Обойти это можно, как показывает Тим в своей статье, создав пакет с коллекцией, инициализировав эту коллекцию в триггере оператора before, заполнив данные в коллекции триггером на уровне строк, а затем обработав измененные строки втриггер после оператора.Однако это довольно сложная задача для добавления в систему, поскольку вам придется управлять несколькими различными объектами.
Как правило, вам лучше реализовать эту логику как часть любого 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;