Триггер SQL для таблицы аудита - PullRequest
3 голосов
/ 08 июня 2010

Я пишу триггер для аудита обновлений и удалений в таблицах.Я использую SQL Server 2008

Мои вопросы:

Есть ли способ узнать, какое действие выполняется с записью, не проходя этап выбора удаленных и вставленных таблиц?

Другой вопрос: если запись удаляется, как мне записать в таблицу аудита пользователя, который выполняет удаление.(ПРИМЕЧАНИЕ: пользователь, подключенный к базе данных, является строкой общего подключения с установленным пользователем, мне нужен пользователь, вошедший в веб-приложение или приложение для Windows)

Пожалуйста, помогите?

Ответы [ 4 ]

4 голосов
/ 08 июня 2010

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

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

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

Когда вы пишете свои триггеры, убедитесь, что они могут обрабатывать многострочные вставки / обновления / удаления.Триггеры работают со всем набором данных, а не по одной строке за раз.

3 голосов
/ 08 июня 2010

Для первой части вы можете установить отдельные триггеры или иметь один триггер, который проверяет специальные таблицы INSERTED и DELETED для различения обновлений и удалений.

Что касается второй части, в этом случае нет никакого способа обойти это, вам придется каким-то образом получить это имя пользователя в базе данных через ваше приложение web / windows. К сожалению, вы не можете связаться с самим триггером, и с общей строкой соединения БД не имеет ни малейшего представления, с кем имеет дело.

Я обнаружил, что может быть полезно добавить столбец «LastModifiedBy» в таблицы, которые вы планируете проверять, чтобы вы могли хранить эту информацию в самих исходных таблицах. Тогда ваш триггер просто копирует эту информацию в таблицу аудита. Это также хорошо, потому что, если вам нужно только знать, кто последним коснулся чего-либо, вам вообще не нужно просматривать таблицу аудита, просто отметьте этот столбец.

3 голосов
/ 08 июня 2010

Как сказал roufamatic, вы можете настроить триггеры, специфичные для каждого действия, или проверить их по таблицам INSERTED и DELETED.

Что касается пользователя, удаляющего эту информацию, то можно передать эту информацию в триггер.до тех пор, пока код в вашем приложении обрабатывает его.Я столкнулся с этим требованием около года назад с клиентом, и я решил использовать SET CONTEXT_INFO и CONTEXT_INFO () для передачи имени пользователя.Доступ к нашей базе данных осуществлялся через хранимые процедуры, поэтому мне просто нужно было добавить одну или две строки кода в хранимые процедуры удаления в SET CONTEXT_INFO, а затем я изменил триггеры удаления, чтобы получить пользователя из CONTEXT_INFO ().Имя пользователя должно быть передано как параметр из приложения, конечно.Если вы не используете хранимые процедуры, вы можете просто выполнить SET CONTEXT_INFO в приложении.Я не знаю, как пул соединений может повлиять на этот метод.Очевидно, что если кто-то сделает удаление за пределами приложения, записи об этом не будет, если только вы отдельно не захватите USERNAME () в своем триггере (вероятно, это хорошая идея, хотя это не было необходимо для нашего журнала аудита, которыйбыло больше для отчетности, чем для безопасности).

Была небольшая хитрость, потому что CONTEXT_INFO - это двоичная строка, но это не заняло много времени, чтобы разобраться со всем.

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

1 голос
/ 08 июня 2010

Чтобы узнать, какие действия предпринимаются, вы можете использовать таблицы INSERTED и DELETED для сравнения значений до и после. Нет волшебного способа узнать, какой пользователь веб-приложения внес изменения. Обычный метод состоит в том, чтобы иметь измененный столбец в вашей таблице и заполнить код веб-приложения соответствующим именем пользователя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...