PostgreSQL: проверка на NEW и OLD в функции для триггера
Я хочу создать триггер, который считает строки и обновляет поле в другой таблице. Мое текущее решение работает для операторов INSERT, но не удается, когда я удаляю строку.
Моя текущая функция:
CREATE OR REPLACE FUNCTION update_table_count()
RETURNS trigger AS
$$
DECLARE updatecount INT;
BEGIN
Select count(*) into updatecount
From source_table
Where id = new.id;
Update dest_table set count=updatecount
Where id = new.id;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
Триггер довольно простой, выглядит как.
CREATE TRIGGER count_trigger
AFTER INSERT OR DELETE
ON source_table
FOR EACH ROW
EXECUTE PROCEDURE update_table_count();
Когда я выполняю инструкцию DELETE, возникает следующая ошибка:
ОШИБКА: запись "новая" еще не назначена
ДЕТАЛИ: структура кортежа еще не назначенной записи является неопределенной.
Я знаю, что одним из решений может быть создание только одного набора триггеров и функций для DELETE и одного для оператора INSERT. Но я хочу сделать это более элегантно и узнать, есть ли решение, чтобы проверить, присутствует ли NEW или OLD в текущем контексте, и просто реализовать блок IF ELSE. Но я не знаю, как проверить этот контекст чувствительных элементов.
Спасибо за вашу помощь
2 ответа
Обычный подход к выполнению функции триггера в зависимости от того, как сработал триггер, заключается в проверке операции триггера через TG_OP.
CREATE OR REPLACE FUNCTION update_table_count()
RETURNS trigger AS
$$
DECLARE
updatecount INT;
BEGIN
if tg_op = 'UPDATE' then
select count(*) into updatecount from source_table where id = new.id;
update dest_table set count=updatecount where id = new.id;
elsif tg_op = 'DELETE' then
... do something else
end if;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
Не связано, но: название языка является идентификатором. Не цитируйте его, используя одинарные кавычки.
From PostgreSQL's documentation:
NEW
Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is null in statement-level triggers and for DELETE operations.
OLD
Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. This variable is null in statement-level triggers and for INSERT operations.
So, for example, if NEW is NULL, then the trigger was invoked on DELETE.