Tengo 10 procedimientos almacenados y cada uno de ellos INSERTA en una tablaX.
¿Es posible en un cuerpo de activación de tableX obtener qué objeto causa la modificación de tableX (proc1 almacenado o sp2 o ...)?
Gracias.
fuente
Tengo 10 procedimientos almacenados y cada uno de ellos INSERTA en una tablaX.
¿Es posible en un cuerpo de activación de tableX obtener qué objeto causa la modificación de tableX (proc1 almacenado o sp2 o ...)?
Gracias.
Sí, es posible identificar el código en ejecución, utilizando la función de sistema @@ procid , y mejor OBJECT_NAME (@@ PROCID) para tener el nombre completo.
Definición: "Devuelve el identificador de objeto (ID) del módulo Transact-SQL actual. Un módulo Transact-SQL puede ser un procedimiento almacenado, una función definida por el usuario o un disparador. @@ PROCID no se puede especificar en los módulos CLR o en el proveedor de acceso a datos de proceso ".
Puedes leer sobre esto aquí .
Otra opción sería verificar el plan sql del spid actual y guardar esa información en una tabla de registro. Una consulta de muestra que se utilizará en cada procedimiento para guardar datos de auditoría sería:
select sp.hostname, sp.program_name, sp.loginame,
st.text as query_text
from sysprocesses sp
cross apply sys.dm_exec_sql_text(sp.sql_handle) as st
where sp.spid = @@spid
Tal vez hay demasiados detalles allí ... pero creo que entiendes la idea.
Una tercera opción sería utilizar la información context_info para la sesión del SP actual. Y asocie en algún lugar la información de contexto guardada allí con cada procedimiento. Por ejemplo, en el procedimiento 1, escribe 111 en el contexto, en el procedimiento 2, escribe 222 ... y así sucesivamente.
Puede leer mucha más información sobre context_info en esta pregunta SO .
OBJECT_NAME(@@PROCID)
devuelve el nombre del disparador, no el proceso de llamada.Yo también quería hacer esto. Gracias por la respuesta. Como todavía estoy aquí, publicaré mi prueba para ahorrar tiempo a otros :)
fuente
XEvents proporciona otra forma de dar a conocer una pila T-SQL aunque SQL Server 2008 podría no admitir un tipo de evento usado. La solución consiste en un disparador, un error y una sesión XEvent. Tomé el ejemplo de Jim Brown para mostrar cómo funciona.
En primer lugar, probé la solución para SQL Server 2016 SP2CU2 Dev Edition. SQL Server 2008 admite algunos EXevent, pero no tengo ninguna instancia, por lo que no pude probarlo.
La idea es generar un error de usuario en un bloque ficticio try-catch, luego detectar el error dentro de una sesión XEvent con
tsql_stack
acción.SQLSERVER.error_reported
El tipo XEvent puede detectar todos los errores aunque un bloque try-catch los atrape. Al final,sys.dm_exec_sql_text
extraiga las consultas T-SQL de los controles de consulta quetsql_stack
da la acción.A continuación se muestra un ejemplo de la respuesta de Jim Brown, que desarrollé. Un disparador genera el error con el texto 'atraparme'. La sesión de XEvent detecta errores solo con el texto como "Atrápame".
Ahora, si inicia la sesión XEvent (SSMS, Object Explorer, Management, Extended Events, Sessions, catch_insertion_into_Test), ejecute usp_RootProcIDTest y mire el búfer en anillo de la sesión XEvent, debería ver el XML que consiste en el nodo
<action name="tsql_stack" package="sqlserver">
. Hay una secuencia de nodos de trama. Ponga los valores de unhandle
atributo 's en la función del sistema' sys.dm_exec_sql_text ', y voilà:¡XEvent te permite hacer mucho más que esto! ¡No pierdas las oportunidades de aprenderlas!
fuente