Аудит каждой вставленной строки в триггере

Я пытаюсь сделать историю аудита, добавив триггеры в мои таблицы и вставив строки в мою таблицу аудита. У меня есть хранимая процедура, которая делает вставку немного проще, потому что она сохраняет код; Мне не нужно выписывать весь оператор вставки, но вместо этого я выполняю хранимую процедуру с несколькими параметрами столбцов, которые я хочу вставить.

Я не уверен, как выполнить хранимую процедуру для каждой строки в "вставленной" таблице. Я думаю, может быть, мне нужно использовать курсор, но я не уверен. Я никогда не использовал курсор раньше.

Поскольку это аудит, мне нужно сравнить значение для каждого старого столбца с новым, чтобы увидеть, изменилось ли оно. Если это изменилось, я выполню хранимую процедуру, которая добавит строку в мою таблицу аудита.

Какие-нибудь мысли?

4 ответа

Я бы обменял пространство на время и не делал сравнения. Просто вставьте новые значения в таблицу аудита при вставке / обновлении. Диск дешевый.

Кроме того, я не уверен, что хранимая процедура покупает вас. Разве вы не можете сделать что-то простое в триггере, как:

insert into dbo.mytable_audit
    (select *, getdate(), getdate(), 'create' from inserted)

Где триггер запускается при вставке, и вы добавляете поля времени создания, времени последнего обновления и типа модификации. Для обновления это немного сложнее, так как вам нужно будет предоставить именованные параметры, так как созданное время не должно обновляться

insert into dbo.mytable_audit (col1, col2, ...., last_updated, modification)
     (select *, getdate(), 'update' from inserted)

Кроме того, планируете ли вы проверять только успехи или неудачи? Если вы хотите проверять сбои, вам понадобится нечто иное, чем триггеры, я думаю, так как триггер не будет запущен, если транзакция откатывается, и у вас не будет статуса транзакции, если триггер запускается первым.

Я фактически переместил свой аудит на уровень доступа к данным и теперь делаю это в коде. Это облегчает как аудит успеха, так и неудачи, и (используя отражение) довольно легко копировать поля в объект аудита. Еще одна вещь, которую он позволяет мне сделать, это дать контекст пользователя, поскольку я не даю фактические пользовательские разрешения для базы данных и не выполняю все запросы с использованием учетной записи службы.

Если ваша база данных должна масштабироваться за несколько пользователей, это станет очень дорого. Я бы порекомендовал изучить сторонние инструменты аудита баз данных.

Уже есть встроенная функция UPDATE() который сообщает вам, изменился ли столбец (но это касается всего набора вставленных строк).

Вы можете посмотреть на некоторые приемы в триггерах AutoAudit Пола Нильсена, которые генерируются кодом.

Что он делает, это проверяет оба:

IF UPDATE(<column_name>)
INSERT Audit (...)
SELECT ...
FROM Inserted
JOIN Deleted
    ON Inserted.KeyField = Deleted.KeyField -- (AutoAudit does not support multi-column primary keys, but the technique can be done manually)
AND NOT (Inserted.<column_name> = Deleted.<column_name> OR COALESCE(Inserted.<column_name>, Deleted.<column_name>) IS NULL)

Но он проверяет каждое изменение столбца в виде отдельной строки. Я использую его для аудита изменений в таблицах конфигурации. В настоящее время я не использую его для аудита таблиц тяжелых изменений. (Но в большинстве транзакционных систем, которые я разработал, строки в таблицах с высокой активностью обычно неизменны, у вас не так много UPDATEс, просто много INSERTs - так что вам даже не понадобится такой вид одитинга). Например, заказы или записи в бухгалтерской книге никогда не меняются, а корзины покупок одноразовые - такого же аудита не было бы. На таблицах изменений малого объема, таких как клиенты, вы можете использовать этот вид аудита.

Джефф, я согласен с Зодеусом... хороший вариант - использовать третий инструмент. Я использовал веб-инструмент auddatabase (FREE), который генерирует триггеры аудита (вам не нужно писать ни одной строки кода TSQL)

Еще одним хорошим инструментом является Apex SQL Audit, но он не бесплатный.

Я надеюсь, что это поможет вам, Ф. О'Нил

Другие вопросы по тегам