Información de contexto:
- Estoy creando una colección de tablas de auditoría para realizar un seguimiento de las actualizaciones y eliminaciones en un conjunto de tablas de datos para mi aplicación.
- Los registros de auditoría se crean a través de disparadores.
- El DML en la base de datos de mi aplicación generalmente vendrá de un inicio de sesión que un servicio utiliza para ingresar a la base de datos. Debido a esto, creo que el resultado
SYSTEM_USER
siempre será el mismo cuando se llama en un disparador. - Mi aplicación no almacena datos de usuario actualmente, aunque
UserId
se le asigna una cadena cada vez que se realiza DML (se realiza exclusivamente en procedimientos almacenados).
El problema con el que me encontré es que cuando un usuario elimina un registro, quiero saber quién lo hizo. Debido a que se realizará mediante el mismo inicio de sesión, no quiero ver que todas las acciones se realizaron por servicio, quiero ver qué usuario lo hizo. Esto no es un problema en una actualización, porque tenemos ModifiedBy
columnas que se actualizarán a través de actualizaciones enviadas UserId
.
La pregunta es: ¿hay alguna manera de configurar SYSTEM_USER
u obtener la información del usuario en el activador cuando se ejecuta una eliminación?
La "mejor" idea que tengo en este momento, aunque no estoy seguro de si es una buena idea todavía, es que en el servicio verifico si el UserId
usuario actual está en la base de datos, y si no es así, creo un usuario objeto para ellos. Luego ejecute procedimientos almacenados con EXECUTE AS User = @UserId
. Luego, cuando DML se realiza en el procedimiento almacenado y se dispara el disparador, SYSTEM_USER
debe devolver al usuario de EXECUTE AS
.
fuente
Respuestas:
Durante el uso
EXECUTE AS User = @UserId
puede ser su mejor opción (dependiendo de otros problemas), aquí hay un enfoque alternativo:En los procedimientos almacenados, o en cualquier momento de su sesión SQL antes de
DELETE
ejecutar, ejecute el siguiente comando:Luego, en su Trigger puede recuperar este valor con
Esto tiene algunas desventajas, la más importante de las cuales es que no puede usar CONTEXT_INFO para más de una cosa a la vez.
fuente
Dependiendo de cómo cambie el contexto del usuario del inicio de sesión individual al inicio de sesión del servicio, puede encontrar que ORIGINAL_LOGIN () es útil.
http://technet.microsoft.com/en-us/library/ms189492.aspx
"Esta función puede ser útil para auditar la identidad del contexto de conexión original. Mientras que funciones como SESSION_USER y CURRENT_USER devuelven el contexto de ejecución actual, ORIGINAL_LOGIN devuelve la identidad del inicio de sesión que se conectó por primera vez a la instancia de SQL Server en esa sesión".
fuente
También podría intentar agregar
Host_Name
a sus tablas. He encontrado en situaciones en las que tengo un inicio de sesión compartido que generalmente puedo rastrear a un individuo por su nombre de máquina desde el 95% del tiempo que una persona está trabajando desde su propia máquina. No siempre funciona, pero puede ser una información secundaria útil.Lamentablemente, esto no funcionará si está trabajando con una aplicación web en la que el host siempre será la aplicación web en sí, pero puede valer la pena intentarlo.
fuente