Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Kann eindeutig festgestellt werden, ob ein DML-Befehl von einer gespeicherten Prozedur ausgegeben wurde?

Verwenden Sie CONTEXT_INFO (Transact-SQL) . Legen Sie in der Prozedur einen Wert fest, um den Trigger darauf hinzuweisen, nichts aufzuzeichnen:

--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 

Überprüfen Sie im Trigger CONTEXT_INFO und stellen Sie fest, ob Sie etwas tun müssen:

--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

Für jeden, der nur ein Rogue-Einfügen / Aktualisieren / Löschen durchführt, hat er CONTEXT_INFO nicht festgelegt, und der Trigger zeichnet die Änderung auf. Sie könnten sich mit dem Wert, den Sie in CONTEXT_INFO eingeben, wie dem Tabellennamen oder @@SPID usw. etwas einfallen lassen, wenn Sie glauben, dass der Schurkencode versuchen wird, CONTEXT_INFO ebenfalls zu verwenden.