Триггеры в PostgreSQL
recordid | patientid | doctorid | dateofrecord | updated_at
----------+-----------+----------+--------------+----------------------------
7 | 3 | 4 | 2020-02-01 | 2020-11-23 18:02:06.627431
8 | 4 | 4 | 2020-05-12 | 2020-11-23 18:02:06.627431
1 | 1 | 3 | 2020-02-01 | 2020-11-23 18:02:06.627431
3 | 3 | 3 | 2020-12-23 | 2020-11-23 18:02:06.627431
9 | 5 | 3 | 2020-12-23 | 2020-11-23 18:02:06.627431
12 | 3 | 3 | 2020-04-12 | 2020-11-23 18:02:06.627431
13 | 4 | 3 | 2020-02-01 | 2020-11-23 18:02:06.627431
4 | 1 | 3 | 2020-04-01 | 2020-11-23 18:02:06.627431
6 | 1 | 3 | 2020-02-01 | 2020-11-23 18:02:06.627431
11 | 2 | 3 | 2020-05-12 | 2020-11-23 18:02:06.627431
Пишу тригер для таблици на обновление поля updated_at.Тригер должен обновлять поле updated_at на дату(now()) когда обновляю запись в таблице. Вот что я пробывал делать,но почему не работает так.Подскажите что изменить или добавить нужно :
create or replace function update_records() returns trigger
as $$
begin
update records set updated_at=now() where id=old.id;
return old;
end;
$$ language plpgsql;
drop trigger if exists tr_update_records on records;
create trigger tr_update_records after update on records
for each row execute procedure update_records();
Ответы (2 шт):
Поменяй триггер на BEFORE UPDATE и вместо
update records set updated_at=now() where id=old.id;
return old;
сделай
NEW.updated_at=now();
return NEW;
Кратко:
CREATE OR REPLACE FUNCTION public.update_records()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END
$function$;
create trigger tr_update_records before update on records
for each row execute procedure update_records();
before update триггер и в самом триггере меняется сама обновляемая строка, а не вызывается бесконечный рекурсивный update.
Вы пытаетесь сделать update из триггера. По этой же самой таблице. Вы считаете, что есть причина, почему update из триггера не должен спровоцировать вызов этого же самого триггера? Нет, такой причины нет. И по той же самой строке тоже. Ваш триггер рекурсивно провоцирует обновление таблицы и вызов самого себя до самого
ERROR: stack depth limit exceeded
Но, главное, вам вовсе не нужен этот update. Поскольку вам нужно изменить строку, которую вы пишете прямо сейчас в этой операции - вам нужен before update триггер, который вызывается перед записью новой строки, а, следовательно, это подходящее место для редактирования строки. Для этого у вас есть и OLD и NEW и возможность вернуть из триггера любую структуру record, которая будет использоваться для записи в этой операции. То есть манипулируя NEW можно как угодно менять содержимое этой строки.