Исходная информация:
- Я создаю коллекцию таблиц аудита для отслеживания обновлений и удалений в наборе таблиц данных для моего приложения.
- Аудиторские записи создаются с помощью триггеров.
- DML в базе данных моего приложения обычно поступает от имени входа, которое служба использует для входа в базу данных. Из-за этого, я думаю, что результат
SYSTEM_USER
всегда будет одинаковым при вызове в триггере. - Мое приложение не хранит пользовательские данные в настоящее время, хотя
UserId
ему каждый раз передается строка (выполняется исключительно в хранимых процедурах).
Проблема, с которой я столкнулся, заключается в том, что когда пользователь удаляет запись, я хочу знать, кто это сделал. Поскольку это будет сделано при том же входе в систему, я не хочу видеть, что все действия были выполнены службой, я хочу видеть, какой пользователь это сделал. Это не проблема для обновления, потому что у нас есть ModifiedBy
столбцы, которые будут обновляться через отправленные UserId
обновления.
Вопрос заключается в следующем: есть ли способ установить SYSTEM_USER
или иным образом получить информацию о пользователе в триггер при запуске удаления?
«Лучшая» идея, которая у меня есть сейчас, хотя я не уверен, что это хорошая идея, заключается в том, что в сервисе я проверяю, находится ли текущий пользователь UserId
в базе данных как пользователь, и, если нет, создает пользователя. объект для них. Затем запустите хранимые процедуры с помощью EXECUTE AS User = @UserId
. Затем, когда DML будет выполнен в хранимой процедуре и триггер срабатывает, SYSTEM_USER
следует вернуть пользователя из EXECUTE AS
.
источник
Ответы:
Хотя использование
EXECUTE AS User = @UserId
может быть вашим лучшим вариантом (в зависимости от других проблем), вот альтернативный подход:В хранимых процедурах или в любое время сеанса SQL перед
DELETE
выполнением выполните следующую команду:Затем в вашем триггере вы можете получить это значение с помощью
Это имеет ряд недостатков, наиболее важным из которых является то, что вы не можете легко использовать CONTEXT_INFO для более чем одной вещи одновременно.
источник
В зависимости от того, как вы меняете пользовательский контекст с индивидуального имени входа на имя входа службы, может оказаться полезным ORIGINAL_LOGIN ().
http://technet.microsoft.com/en-us/library/ms189492.aspx
«Эта функция может быть полезна при проверке подлинности исходного соединительного контекста. В то время как функции, такие как SESSION_USER и CURRENT_USER, возвращают текущий исполняемый контекст, ORIGINAL_LOGIN возвращает идентификатор входа в систему, который первым подключился к экземпляру SQL Server в этом сеансе».
источник
Вы также можете попробовать добавить
Host_Name
в свои таблицы. Я обнаружил, что в тех случаях, когда у меня есть общая учетная запись, я обычно могу отследить человека по имени его машины, поскольку 95% времени человек работает со своей собственной машины. Это не всегда работает, но это может быть полезной дополнительной информацией.К сожалению, это не сработает, если вы работаете с веб-приложением, хостом которого всегда будет само веб-приложение, но, возможно, стоит попробовать.
источник