Saltar al contenido

SQL Server: ¿Cómo deshabilitar el disparador de una actualización solo para su sesión actual?

Queremos mostrarte la mejor solución que hemos encontrado en línea. Nosotros queremos que te resulte útil y si puedes comentarnos algo que nos pueda ayudar a perfeccionar nuestra información hazlo con libertad.

Solución:

Para resolver su problema, debemos adoptar un enfoque programático del problema. Hay dos rutas a las que puede ir aquí. La razón por la que se necesitan estos enfoques es porque no puede deshabilitar un disparador para una declaración en particular, solo se puede deshabilitar para la totalidad de la tabla.

Opción 1: Context_Info ()

Samuel Vanga en MS SQL Tips tuvo un gran ejemplo:

USE AdventureWorks; 
GO 
-- creating the table in AdventureWorks database 
IF OBJECT_ID('dbo.Table1') IS NOT NULL 
DROP TABLE dbo.Table1 
GO 
CREATE TABLE dbo.Table1(ID INT) 
GO 
-- Creating a trigger 
CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE 
AS 
DECLARE @Cinfo VARBINARY(128) 
SELECT @Cinfo = Context_Info() 
IF @Cinfo = 0x55555 
RETURN 
PRINT 'Trigger Executed' 
-- Actual code goes here 
-- For simplicity, I did not include any code 
GO

Ahora, cuando Samuel no quiere que se ejecute el disparador, usan esto:

SET Context_Info 0x55555 
INSERT dbo.Table1 VALUES(100)

Context_Info utiliza las siguientes vistas del sistema para obtener información sobre la sesión actual:

  • sys.dm_exec_requests

  • sys.dm_exec_sessions

  • sys.sysprocesses

La ideología aquí es que el binario string que está configurando está expuesto solo a la sesión actual, por lo que cuando el disparador se ejecuta durante su sesión, verá el alcance y la configuración de la variable de la Context_info función y saltará a la parte de escape del disparador en su lugar.

Opción 2: Tabla de temperatura

Itzik Ben-Gan tiene una gran solución en su libro “Inside Microsoft SQL Server 2008 T-SQL Programming: T-SQL Programming”, que también se encuentra en su último libro T-SQL Querying. El problema principal con esto sobre el context_info La función es la sobrecarga menor de TempDB.

Para estropear la sorpresa pero no arruinar la trama de los libros (sentí que vale la pena comprarlos y leerlos), alterarás tu disparador.

Su activador debe realizar una verificación de una tabla temporal. Si la tabla temporal existe, el disparador debe saber finalizar y no realizar las acciones.

En la declaración de actualización que desea realizar, primero cree la tabla temporal. Se verá en la misma transacción que el disparador y hará que el disparador ignore su estado de cuenta.

Ejemplo de disparador:

CREATE TRIGGER TRIGGERNAME ON TABLENAME for INSERT AS

IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
GO

Ejemplo de declaración inicial cuando no desea que se ejecute el disparador:

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);

Poniéndolo en conjunto para tu ejemplo:

ALTER TRIGGER tiu_benefit ON benefit FOR 
... 
AS
...
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
--... rest of code here
GO

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
UPDATE benefit SET editor = 'srh' where benefit_id = 9876;
GO

Hice algunas pruebas sobre esto y creo que estaría bien si ejecuta su proceso en una sola transacción.

BEGIN TRANSACTION
GO

DISABLE TRIGGER tiu_benefit ON benefit;
GO

UPDATE benefit
SET editor = 'srh'
WHERE benefit_id = 9876
GO

ENABLE TRIGGER tiu_benefit ON benefit;
GO

--Decide to commit or rollback

--commit
--rollback 

En mi prueba, solo resalté y ejecuté el BEGIN TRANSACTION y el DISABLE TRIGGER primero. Luego abrí una nueva (segunda) ventana de consulta e intenté ejecutar varias declaraciones DML (SELECT, INSERT, UPDATEDELETE) contra la mesa base. Todos los intentos de acceder a la tabla base en la segunda ventana de consulta esperaron los bloqueos mantenidos por la ventana con la transacción explícita. Una vez que comprometí (o deshice) mi transacción explícita, la segunda ventana pudo acceder a la tabla.

Yo usaría cualquiera de los dos CONTEXT_INFO o el mas nuevo SESSION_CONTEXT. Ambos son valores basados ​​en sesiones.

  • CONTEXT_INFO es un soltero VARBINARY(128) valor. Esto ha estado disponible desde al menos SQL Server 2000. CONTEXT_INFO es visible para cualquier persona con VIEW SERVER STATE ya que es un campo devuelto por el sys.dm_exec_sessions DMV. He usado este antes y funciona bastante bien.

    Establecer mediante SET CONTEXT_INFO
    Obtener a través de CONTEXT_INFO () o sys.dm_exec_sessions

    Dependiendo del tipo de valor que está almacenando CONTEXT_INFO, hay algunos matices a tener en cuenta. Cubro eso en la siguiente publicación del blog:

    ¿Por qué CONTEXT_INFO () no devuelve el valor exacto establecido por SET CONTEXT_INFO?

  • Session_context es un key/ valor par de SQL_VARIANT valores. Esto se introdujo en SQL Server 2016. La separación de valores para diferentes propósitos es bastante agradable. Session_context solo es visible para la sesión actual.

    Establezca este valor a través de sp_set_session_context
    Obtenga este valor a través de SESSION_CONTEXT

Una cosa a considerar con respecto a la opción de tabla temporal local e incluso la opción de activación / desactivación de activación: ambas requieren cierta cantidad de actividad de bloqueo y registro. Ambas opciones aumentan el potencial de contención, aunque sea mínimamente. Las dos opciones de “contexto” deberían ser más ligeras / solo de memoria.

valoraciones y reseñas

Nos puedes corroborar nuestro cometido añadiendo un comentario y dejando una valoración te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *