Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

È possibile identificare in modo definitivo se un comando DML è stato emesso da una procedura memorizzata?

Usa CONTEXT_INFO (Transact-SQL) . Nella procedura impostare un valore per avvisare il trigger di non registrare nulla:

--in the procedure doing the insert/update/delete

DECLARE @CONTEXT_INFO  varbinary(128)
SET @CONTEXT_INFO =cast('SkipTrigger=Y'+REPLICATE(' ',128) as varbinary(128))
SET CONTEXT_INFO @CONTEXT_INFO

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

SET CONTEXT_INFO 0x0 

Nel trigger controlla CONTEXT_INFO e determina se devi fare qualcosa:

--here is the portion of the trigger to retrieve the value:

IF CAST(CONTEXT_INFO() AS VARCHAR(128))='SkipTrigger=Y'
BEGIN
    --log your data here
END

per chiunque stia solo facendo un inserimento/aggiornamento/eliminazione canaglia, non avrà impostato CONTEXT_INFO e il trigger registrerà la modifica. Potresti divertirti con il valore che hai inserito in CONTEXT_INFO, come il nome della tabella o @@SPID, ecc. se pensi che il codice canaglia tenterà di utilizzare anche CONTEXT_INFO.