Триггер PL / PGSQL как определить, указан ли столбец в инструкции SQL при ОБНОВЛЕНИИ?

#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 an UPDATE — это 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. Очень умно, мне это нравится! Хотя я предлагаю добавить ссылку на документацию о порядке выполнения триггера: «Если для одного и того же события в одном и том же отношении определено более одного триггера, триггеры будут запускаться в алфавитном порядке по имени триггера».