Informações básicas:
- Estou criando uma coleção de tabelas de auditoria para acompanhar as atualizações e exclusões em um conjunto de tabelas de dados para o meu aplicativo.
- Os registros de auditoria são criados por meio de gatilhos.
- O DML no banco de dados do meu aplicativo geralmente vem de um logon que um serviço usa para entrar no banco de dados. Por isso, acho que o resultado de
SYSTEM_USER
sempre será o mesmo quando chamado em um gatilho. - Meu aplicativo não armazena dados do usuário atualmente, embora uma string
UserId
seja fornecida toda vez que o DML for executado (feito exclusivamente em procedimentos armazenados).
O problema que encontrei é que, quando um usuário exclui um registro, quero saber quem o fez. Como será feito pelo mesmo login, não quero ver que todas as ações foram executadas pelo serviço, quero ver qual usuário fez. Esse não é um problema em uma atualização, porque temos ModifiedBy
colunas que serão atualizadas por meio de atualizações enviadas UserId
.
A pergunta é: existe uma maneira de definir SYSTEM_USER
ou colocar as informações do usuário no gatilho quando uma exclusão é executada?
A "melhor" ideia que tenho agora, embora ainda não tenha certeza se é uma boa ideia, é que, no serviço, verifico se a corrente UserId
está no banco de dados como usuário e, se não, crie um usuário objeto para eles. Em seguida, execute os procedimentos armazenados com EXECUTE AS User = @UserId
. Então, quando o DML for concluído no procedimento armazenado e o gatilho for disparado, SYSTEM_USER
o usuário deverá retornar o EXECUTE AS
.
fonte
Respostas:
Embora o uso
EXECUTE AS User = @UserId
seja a melhor opção (dependendo de outros problemas), eis uma abordagem alternativa:Nos procedimentos armazenados, ou a qualquer momento na sua sessão SQL, você deve
DELETE
executar o seguinte comando:Em seu gatilho, você pode recuperar esse valor com
Isso tem algumas desvantagens, a mais importante delas é que você não pode usar prontamente CONTEXT_INFO para mais de uma coisa por vez.
fonte
Dependendo de como você altera o contexto do usuário do logon individual para o logon do serviço, você pode achar que ORIGINAL_LOGIN () é útil.
http://technet.microsoft.com/en-us/library/ms189492.aspx
"Esta função pode ser útil na auditoria da identidade do contexto de conexão original. Enquanto funções como SESSION_USER e CURRENT_USER retornam o contexto de execução atual, ORIGINAL_LOGIN retorna a identidade do logon que primeiro foi conectado à instância do SQL Server nessa sessão."
fonte
Você também pode tentar adicionar
Host_Name
às suas tabelas. Constatei que em situações em que tenho um login compartilhado, geralmente consigo rastrear uma pessoa pelo nome de sua máquina, já que 95% do tempo em que uma pessoa está trabalhando em sua própria máquina. Nem sempre funciona, mas pode ser uma informação secundária útil.Infelizmente, isso não funcionará se você estiver trabalhando com um aplicativo Web no qual o host sempre será o próprio aplicativo Web, mas pode valer a pena tentar.
fonte