Informations d'arrière-plan:
- Je crée une collection de tables d'audit pour suivre les mises à jour et les suppressions d'un ensemble de tables de données pour mon application.
- Les enregistrements d'audit sont créés via des déclencheurs.
- DML dans la base de données de mon application proviendra généralement d'une connexion qu'un service utilise pour accéder à la base de données. Pour cette raison, je pense que le résultat de
SYSTEM_USER
sera toujours le même lorsqu'il est appelé dans un déclencheur. - Mon application ne stocke pas de données utilisateur actuellement, bien qu'une chaîne lui
UserId
soit donnée à chaque fois que DML doit être fait (fait exclusivement dans les procédures stockées).
Le problème que j'ai rencontré est que lorsqu'un utilisateur supprime un enregistrement, je veux savoir qui l'a fait. Parce que cela se fera par la même connexion, je ne veux pas voir que toutes les actions ont été effectuées par le service, je veux voir quel utilisateur l'a fait. Ce n'est pas un problème sur une mise à jour, car nous avons des ModifiedBy
colonnes qui seront mises à jour via un envoyé UserId
sur les mises à jour.
La question est la suivante: existe-t-il un moyen de définir SYSTEM_USER
ou d'obtenir autrement les informations utilisateur dans le déclencheur lorsqu'une suppression est exécutée?
La "meilleure" idée que j'ai en ce moment, bien que je ne sois pas encore sûre que ce soit une bonne idée, est que dans le service, je vérifie si le courant UserId
est dans la base de données en tant qu'utilisateur, et si ce n'est pas le cas, créez un utilisateur objet pour eux. Exécutez ensuite les procédures stockées avec EXECUTE AS User = @UserId
. Ensuite, lorsque DML est terminé dans la procédure stockée et que le déclencheur se déclenche, il SYSTEM_USER
doit renvoyer l'utilisateur à partir du EXECUTE AS
.
la source
Réponses:
Bien que l'utilisation
EXECUTE AS User = @UserId
puisse être votre meilleure option (en fonction d'autres problèmes), voici une approche alternative:Dans vos procédures stockées, ou à tout moment dans votre session SQL avant d'
DELETE
exécuter la commande suivante:Ensuite, dans votre déclencheur, vous pouvez récupérer cette valeur avec
Cela présente certains inconvénients, dont le plus important est que vous ne pouvez pas facilement utiliser CONTEXT_INFO pour plus d'une chose à la fois.
la source
Selon la façon dont vous modifiez le contexte utilisateur de la connexion individuelle à la connexion au service, vous pouvez trouver que ORIGINAL_LOGIN () est utile.
http://technet.microsoft.com/en-us/library/ms189492.aspx
"Cette fonction peut être utile pour auditer l'identité du contexte de connexion d'origine. Alors que des fonctions telles que SESSION_USER et CURRENT_USER renvoient le contexte d'exécution actuel, ORIGINAL_LOGIN renvoie l'identité de la connexion qui s'est connectée pour la première fois à l'instance de SQL Server dans cette session."
la source
Vous pouvez également essayer d'ajouter
Host_Name
à vos tables. J'ai trouvé dans des situations où j'ai une connexion partagée que je peux généralement retrouver une personne par son nom de machine depuis 95% du temps qu'une personne travaille à partir de sa propre machine. Cela ne fonctionne pas toujours, mais cela peut être une information secondaire utile.Malheureusement, cela ne fonctionnera pas si vous travaillez avec une application Web où l'hôte sera toujours l'application Web elle-même, mais cela peut valoir la peine d'être essayé.
la source