#postgresql #triggers #plpgsql
#postgresql #триггеры #plpgsql
Вопрос:
Я пишу триггер PLPGSQL в Postgres и хочу определить, указан ли столбец в инструкции update. У меня есть идентификатор пользователя, который я хочу использовать для отслеживания изменений. проблема в том, что если идентификатор пользователя уже есть в записи, которую я хочу обновить, а SQL ОБНОВЛЕНИЯ не предоставляет идентификатор пользователя, используется старый идентификатор пользователя. Я хочу определить, не предоставляет ли запрос идентификатор пользователя при обновлении, чтобы вызвать исключение. Достижимо ли это в триггере или мне нужно обязательно всегда добавлять идентификатор пользователя во все запросы?
Например, это должно вызвать исключение:
UPDATE table SET field1 = 'test' WHERE id=1
Это должно полностью запустить триггер, потому что идентификатор пользователя находится в обновлении:
UPDATE table SET field1 = 'test',user_id = 2 WHERE id=1
Я выполняю аудит и хочу быть уверенным, что user_id всегда является частью запроса.
Спасибо
Комментарии:
1. Пожалуйста, опубликуйте образцы входных и выходных данных, которые вы ожидаете.
2. например: это должно вызвать исключение
UPDATE table SET field1 = 'test' WHERE id=1
, это должно полностью запустить триггер, потому что идентификатор пользователя указан в обновленииUPDATE table SET field1 = 'test'
, user_id = 2, ГДЕ id = 1` Я выполняю аудит и хочу быть уверенным, что идентификатор пользователя всегда является частью запроса.3. Как насчет случая, когда
user_id
предоставляется, но он совпадает с существующим? Проблема в том, что в Postgres anUPDATE
— этоDELETE
/INSERT
. Это означает, что в триггерной функцииNEW
иOLD
«таблицы» будут иметь все значения столбцов. Так что, с его точки зренияuser_id
, он всегда есть. Лучшее, что вы можете сделать, это посмотреть, изменилось ли его значение. Дополнительную информацию смотрите Здесь . Возможно, вы захотите просмотреть информацию о пользователе, доступную здесь , и сопоставить сuser_id
.
Ответ №1:
Напишите два AFTER UPDATE
триггера:
-
вызываемый
AFTER UPDATE OF (user_id)
триггерtrigger1
, который содержит толькоRETURN NULL
-
вызываемый
AFTER UPDATE
триггерtrigger2
, который безоговорочно выдает ошибку
Тогда триггеры будут выполняться в таком порядке, потому trigger1
что в алфавитном порядке раньше trigger2
.
Если user_id
он был в SET
списке, trigger1
он выполнит и завершит обработку, потому что он возвращает NULL, поэтому trigger2
он не будет запущен и ошибка не будет выдана.
Если user_id
его нет в SET
lust, trigger1
он не запустится и trigger2
выдаст ошибку.
Смотрите Документацию для объяснения порядка выполнения триггера.
Комментарии:
1. Очень умно, мне это нравится! Хотя я предлагаю добавить ссылку на документацию о порядке выполнения триггера: «Если для одного и того же события в одном и том же отношении определено более одного триггера, триггеры будут запускаться в алфавитном порядке по имени триггера».