ORA-04082: новые или старые ссылки не разрешены в триггерах уровня таблицы
itI имеет таблицу с именем за. В таблице per у меня есть поле с именем "fl1" и другое поле с именем "fl2" . При обновлении записи я хочу проверить, изменилось ли значение "fl1" . Если значение изменилось, обновите столбец "fl2" с новым значением из "fl1" .
Я придумал этот триггер
CREATE OR REPLACE TRIGGER Flag
AFTER INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD
BEGIN
If :New.fl1 != :Old.fl1 Then
:New.fl2:= :new.fl1;
End If;
END;
Я получаю "ORA-04082: NEW или OLD ссылки, которые не разрешены в триггерах уровня таблицы", когда я запускаю его
Другой вариант, о котором я думал (не уверен, будет ли он эффективным), состоит в том, чтобы просто обновить значение "fl2" со значением "fl1" , независимо от того, изменилось ли значение "fl1" .
UPDATE
Добавлено "Для каждой строки" и изменилось "ПОСЛЕ ВСТАВКИ ИЛИ ОБНОВЛЕНИЯ" для "ПЕРЕД ВСТАВКОЙ ИЛИ ОБНОВЛЕНИЕМ". Он работает.
CREATE OR REPLACE TRIGGER Flag
BEFORE INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
If :New.fl1 != :Old.fl1 Then
:New.fl2:= :new.fl1;
End If;
END;
Ответы
Ответ 1
Триггеры DML либо определяются как уровень таблицы, либо как уровень строк.
Триггер уровня таблицы срабатывает один раз для каждой операции в таблице, поэтому, если вы обновляете 30 строк, это одна операция до триггера таблицы. Триггеры таблицы не имеют представления о том, какие строки были изменены, но могут использоваться для регистрации факта, что операция была выполнена.
В этом случае вам понадобится триггер уровня строки, который требует, чтобы "ДЛЯ КАЖДОГО РУКА" включалось в определение триггера. Предложение "REFERENCING" является необязательным, если вы не хотите изменять способ ссылки на новые и старые строки.
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#BABCIBBJ
Не уверен, что точка упражнения здесь. Вы считали, что просто ссылаетесь на fl1 вместо fl2?
Ответ 2
Конечный рабочий код:
CREATE OR REPLACE TRIGGER Flag
BEFORE INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
If :New.fl1 != :Old.fl1 Then
:New.fl2:= :new.fl1;
End If;
END;