Z dobrego podręcznika:
36.1. Przegląd zachowań wyzwalaczy
[...]
W przypadku wyzwalacza na poziomie wiersza dane wejściowe obejmują również NEW
wiersz dla INSERT
i UPDATE
wyzwalacze i/lub OLD
wiersz dla UPDATE
i DELETE
wyzwalacze. Wyzwalacze na poziomie instrukcji nie mają obecnie możliwości sprawdzenia poszczególnych wierszy zmodyfikowanych przez instrukcję.
Oraz z procedur wyzwalania:
NEW
Typ danych RECORD
; zmienna przechowująca nowy wiersz bazy danych dla INSERT
/UPDATE
operacje w wyzwalaczach na poziomie wiersza. Ta zmienna ma wartość NULL
w wyzwalaczach na poziomie instrukcji i dla DELETE
operacje.
Zwróć uwagę, co mówi o wyzwalaczach na poziomie wiersza i wyzwalaczach na poziomie instrukcji.
Masz wyzwalacz na poziomie instrukcji:
...
FOR EACH STATEMENT
EXECUTE PROCEDURE f_log_datei();
Wyzwalacze na poziomie instrukcji są wyzwalane raz na instrukcję, a instrukcja może dotyczyć wielu wierszy, więc pojęcie dotkniętego wiersza (czyli to, co NEW
i OLD
dotyczą) po prostu nie ma zastosowania.
Jeśli chcesz użyć NEW
(lub OLD
) w wyzwalaczu, chcesz, aby wyzwalacz był wykonywany dla każdego wiersza, którego dotyczy problem, a to oznacza, że chcesz wyzwalacza na poziomie wiersza:
CREATE TRIGGER log_datei AFTER INSERT OR UPDATE OR DELETE
ON dateien
FOR EACH ROW
EXECUTE PROCEDURE f_log_datei();
Właśnie zmieniłem FOR EACH STATEMENT
do FOR EACH ROW
.
Twój wyzwalacz powinien również coś zwracać:
Funkcja wyzwalacza musi zwracać NULL
lub wartość rekordu/wiersza o dokładnie takiej samej strukturze tabeli, dla której został uruchomiony wyzwalacz.
[...]
Wartość zwracana wyzwalacza na poziomie wiersza uruchomionego AFTER
lub wyzwalacz na poziomie instrukcji uruchamiany BEFORE
lub AFTER
jest zawsze ignorowana; równie dobrze mogłoby być zerowe. Jednak każdy z tych typów wyzwalaczy może przerwać całą operację, zgłaszając błąd.
Więc powinieneś RETURN NEW;
lub RETURN NULL;
w spuście. Masz wyzwalacz AFTER, więc nie ma znaczenia, którego RETURN użyjesz, ale wybrałbym RETURN NEW;
.