Come posso estrarre la lista dei trigger disabilitati per una o più tabelle, o per l’intero database?
Recentemente, ho avuto la necessità di disabilitare temporaneamente (per alcune ore) tutti i trigger definiti su una tabella. La successiva abilitazione, però, doveva tenere conto dei trigger già disabilitati all’origine, che avevo necessità di conoscere prima di eseguire il comando:
ALTER TABLE <nome_tabella> DISABLE TRIGGER ALL;
…in caso contrario, avrei rischiato di abilitare un trigger che in origine era disabilitato!
Ipotizziamo il seguente scenario: la tabella Production.Product, nel database di esempio AdventureWorks, possiede due oggetti trigger, uno attivo per le operazioni di INSERT ed un altro per le operazioni di UPDATE; il secondo trigger però (quello sull’ON UPDATE) risulta essere disabilitato. Il seguente frammento di codice in linguaggio T-SQL riproduce lo scenario appena descritto.
USE [AdventureWorks]; GO IF OBJECT_ID('Production.TR_INS_Production_Product') IS NOT NULL DROP TRIGGER Production.TR_INS_Production_Product; GO IF OBJECT_ID('Production.TR_UPD_Production_Product') IS NOT NULL DROP TRIGGER Production.TR_UPD_Production_Product; GO CREATE TRIGGER Production.TR_INS_Production_Product ON Production.Product FOR INSERT AS BEGIN PRINT('Hello, I am TR_INS_Production_Product'); END; GO CREATE TRIGGER Production.TR_UPD_Production_Product ON Production.Product FOR UPDATE AS BEGIN PRINT('Hello, I am TR_UPD_Production_Product'); END; GO ALTER TABLE Production.Product DISABLE TRIGGER TR_UPD_Production_Product; GO
I seguenti batch T-SQL, con compatibilità rispettivamente SQL Server 2005, 2008 (R2), 2012 (“Denali”) e SQL Server 2000 permettono di ottenere la lista dei trigger disabilitati per la tabella Production.Product.
Soluzione per SQL Server 2005, 2008 (R2) e 2012 (“Denali”)
Lista trigger disabilitati per la tabella Production.Product.
SELECT s.name AS [Schema Name] ,o.name AS [Table Name] ,t.name AS [Trigger Name] ,CASE WHEN (t.is_disabled = 1) THEN 'Disable' ELSE 'Enable' END AS [Trigger Status] FROM sys.triggers AS t JOIN sys.objects AS o on o.[object_id]=t.[parent_id] JOIN sys.schemas AS s on o.[schema_id]=s.[schema_id] WHERE (s.name = 'Production') AND (o.name = 'Product') AND (is_disabled = 1); GO
L’output è illustrato in figura 1, filtrando la query per lo schema Production e per la tabella Product otteniamo il trigger TR_UPD_Production_Product.
Figura 1 – Trigger disabilitati, definiti sulla tabella Production.Product
Con SQL Server 2000, però, non abbiamo a disposizione la catalog view sys.triggers, dovremo quindi interrogare la proprietà ExecIsTriggerDisabled di ogni oggetto trigger utilizzando la funzione OBJECTPROPERTY.
Soluzione per SQL Server 2000
Lista trigger disabilitati per la tabella Product.
SELECT t.[name] AS [Table Name] ,tr.[name] AS [Trigger Name] ,CASE WHEN (1 = OBJECTPROPERTY(tr.[id], 'ExecIsTriggerDisabled')) THEN 'Disable' ELSE 'Enable' END [Trigger Status] FROM sysobjects t JOIN sysobjects tr ON t.[id] = tr.parent_obj WHERE ((t.xtype = 'U') OR (t.xtype = 'V')) AND (t.name = 'Product') AND (tr.xtype = 'TR') AND (objectproperty(tr.[id], 'ExecIsTriggerDisabled') = 1); GO
L’output è illustrato in figura 2.
Figura 2 – Trigger disabilitati, definiti sulla tabella Product (compatibilità SQL Server 2000)
Conclusioni
Gli ultimi due statement T-SQL permettono di individuare i trigger disabilitati su una determinata tabella nel DB correntemente selezionato. Togliendo il filtro per tabella, è possibile ottenere tutti i trigger disabilitati nel DB corrente.