2010-11-23 20 views
8

Existen algunos procedimientos almacenados que rutinariamente son llamados por algunos sistemas diferentes para realizar tareas de mantenimiento en algunas tablas en nuestra base de datos. Algunos están automatizados, otros no.¿Es posible que un desencadenador encuentre el nombre del procedimiento almacenado que modificó los datos?

Una de las tablas tiene una columna donde el número a veces está desactivado, y no sabemos con certeza cuándo o por qué sucede esto. Quiero poner un disparador sobre la mesa para poder ver qué se cambia y cuándo, pero también sería útil saber qué procedimiento inició la modificación.

¿Es posible obtener el nombre del procedimiento almacenado del disparador? Si no, ¿hay alguna otra forma de decir qué causó que se modificara algo? (No estoy hablando del usuario tampoco, el nombre del usuario no ayuda en este caso).

+0

No creo que sea posible, porque puede ser que no sea un procedimiento almacenado que se ejecutó, puede haber sido un simple lote. Puedo estar equivocado, pero diría que en su caso debería buscar algún tipo de método para obtener una lista de lotes recientes que involucraron una tabla específica, que es esencialmente lo que hace el monitor. – BeemerGuy

Respuesta

3

puede probar: CONTEXT_INFO

aquí es un ejemplo de uso CONTEXT_INFO:

en cada procedimiento de hacer la inserción/eliminación/actualización que desea realizar un seguimiento, añadir lo siguiente:

DECLARE @string  varchar(128) 
     ,@CONTEXT_INFO varbinary(128) 
SET @string=ISNULL(OBJECT_NAME(@@PROCID),'none') 
SET @CONTEXT_INFO =cast('Procedure='[email protected]+REPLICATE(' ',128) as varbinary(128)) 
SET CONTEXT_INFO @CONTEXT_INFO 

--do insert/delete/update that will fire the trigger 

SET CONTEXT_INFO 0x0 --clears out the CONTEXT_INFO value 

aquí está la parte del disparador para recuperar el valor:

DECLARE @string   varchar(128) 
     ,@sCONTEXT_INFO varchar(128) 
SELECT @sCONTEXT_INFO=CAST(CONTEXT_INFO() AS VARCHAR) FROM master.dbo.SYSPROCESSES WHERE [email protected]@SPID 

IF LEFT(@sCONTEXT_INFO,9)='Procedure' 
BEGIN 
    SET @string=RIGHT(RTRIM(@sCONTEXT_INFO),LEN(RTRIM(@sCONTEXT_INFO))-10) 
END 
ELSE 
BEGIN --optional failure code 
    RAISERROR('string was not specified',16,1) 
    ROLLBACK TRAN 
    RETURN 
END 

..use the @string 
+0

@KM, gracias, daré una oportunidad, pero no estoy seguro de si mi equipo estaría encantado de que revisara y modificara cada procedimiento almacenado para la depuración temporal: P – Brandon

+0

estaría aún más emocionado de no reparar el ¿error? los desencadenantes pueden ser dolorosos en algún momento. –

+0

APP_NAME() es útil para rastrear diferentes sistemas. – user423430

-4

No he intentado esto pero @@ PROCID parece que podría devolver lo que usted desea.

+4

Creo que una vez que esté dentro del código de activación, esto devolverá la identificación del disparador. –

+1

correcto. @@ procid (o object_name (@@ procid)) es útil como valor predeterminado de columna en una tabla para saber de dónde vino una inserción. – bwperrin

1

Nuestro sistema ya está utilizando la variable CONTEXT_INFO para otro fin, por lo que no está disponible. También probé el DBCC INPUTBUFFER solution que casi funcionó. El retroceso al buffer de entrada es que solo devuelve el procedimiento de llamada externa. Ej: procA llama a procB que activa un disparador. El disparador ejecuta DBCC INPUTBUFFER que solo muestra procA. Como mi trigger estaba buscando procB, este enfoque falló.

Lo que he hecho mientras tanto es crear una tabla de etapas. Ahora procA llama procB. procB inserta una línea en la tabla de etapas y luego dispara el gatillo. El disparador comprueba la tabla de etapas y encuentra la entrada de procB. Al regresar, procB borra su entrada de la tabla de etapas. Es un juego de shell pero funciona. Me interesaría cualquier comentario sobre esto.

Cuestiones relacionadas