Изменить СТАРОЕ, которое будет возвращено путем УДАЛЕНИЯ в триггерной функции postgresql

#sql #postgresql #triggers #sql-function #postgresql-triggers

#sql #postgresql #триггеры #sql-функция #postgresql-триггеры

Вопрос:

У меня есть триггерная функция в postgresql, которая будет вставлять строки в таблицу аудита при операциях ВСТАВКИ, ОБНОВЛЕНИЯ и УДАЛЕНИЯ. В моих таблицах есть столбец с именем audit_id, и мне нужно записать идентификатор вставленной строки аудита в это поле. Это моя функция

 CREATE OR REPLACE FUNCTION my_audit_trigger()
 RETURNS trigger LANGUAGE plpgsql
AS $function$
declare
  audit_pk bigint;
begin
IF TG_OP = 'INSERT'
THEN
INSERT INTO audit.table_audit (rel_id, table_name, operation, after)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(NEW)) returning id into audit_pk;
 NEW.audit_id := audit_pk;
RETURN NEW;
ELSIF TG_OP = 'UPDATE'
THEN
IF NEW != OLD THEN
 INSERT INTO audit.table_audit (rel_id, table_name, operation, before, after)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(OLD), to_jsonb(NEW)) returning id into audit_pk;
END IF;
 NEW.audit_id := audit_pk;
RETURN NEW;
ELSIF TG_OP = 'DELETE'
THEN
INSERT INTO audit.table_audit (rel_id, table_name, operation, before)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(OLD)) returning id into audit_pk;
OLD.audit_id := audit_pk;
RETURN OLD;
END IF;
end;
$function$;
  

В результате при вставке или обновлении строк моей таблицы я получаю идентификатор аудита соответствующей операции, но когда я запускаю команду УДАЛЕНИЯ, я получаю идентификатор аудита предыдущей операции, а не самого УДАЛЕНИЯ. Итак, я думаю, проблема в OLD.audit_id := audit_pk;

Более конкретно, я запускаю, например INSERT INTO table VALUES (this, that) RETURNING audit_id , и я получаю обратно audit_id операции ВСТАВКИ.

После, при запуске DELETE FROM table WHERE id = sth RETURNING audit_id я получаю audit_id операции ВСТАВКИ, а не УДАЛЕНИЯ.

Любая помощь приветствуется, спасибо.

P.S. Вот как я создаю триггер

 CREATE TRIGGER table_trigger
BEFORE INSERT OR UPDATE OR DELETE
ON table
FOR EACH ROW
EXECUTE PROCEDURE my_audit_trigger();           
  

Комментарии:

1. Я не совсем понимаю. Как вы «возвращаете» что-то из DELETE ?

2. Добро пожаловать в StackOverflow! Не могли бы вы улучшить свой вопрос, поделившись выводом, который вы видите, и тем, что вы ожидаете вместо этого?

3. Когда я запускаю « УДАЛИТЬ ИЗ таблицы, ГДЕ id = 12 ВОЗВРАЩАЕТ * «, я получаю обратно строку, которая возвращается триггерной функцией

4. Мы не можем видеть, как id поле, которое возвращается в audit_pk , получает свое значение, поскольку это поле не указано в инструкции insert. Проблема должна заключаться в том, откуда берется это значение и почему ему присваивается неожиданное значение? В самом триггере нет проблемы, которую я вижу, она должна быть в фактических данных в этой таблице аудита. Имея в виду, что это даже не таблица, в которую записываются инструкции insert или update, так как же это значение устанавливается в affiliate_audit таблице? Только у вас есть доступ к информации, чтобы выяснить это.

5. @404 Идентификатор автоматически генерируется при каждой вставке в таблицу аудита. Я думаю, что эта часть в порядке, поскольку она работает точно так, как ожидалось для ВСТАВКИ и ОБНОВЛЕНИЯ. При выполнении удаления OLD содержит всю удаляемую строку, включая audit_id предыдущей операции. Что я пытаюсь сделать, так это обновить этот старый audit_id новым, но это не работает, я не знаю почему

Ответ №1:

У меня похожая проблема. Похоже, что PG просто не поддерживает модификацию СТАРОГО сейчас, но, возможно, эта функция будет включена в список задач.

В настоящее время вы можете изменять только НОВОЕ для инструкций INSERT и UPDATE

Для получения подробной информации ознакомьтесь с этой почтовой веткой: Поддерживает ли триггер ‘вместо удаления’ модификацию СТАРОГО