¿Cómo puedo eliminar todos los desencadenantes en una sola base de datos?

17

Tengo una base de datos con 104 disparadores, ¿hay alguna manera de eliminar todos los disparadores con un solo comando de una sola base de datos llamada 'system_db_audits?

Mohamed Mahyoub
fuente

Respuestas:

29

Puede usar Dynamic SQL y el sys.triggersDMV para crear consultas que puede ejecutar.

is_ms_shippedexcluye cualquier desencadenante que se envió con SQL Server.
parent_class_descfiltros para disparadores a nivel de objeto, en lugar de nivel de base de datos.

Cambie PRINTa una EXECvez que esté satisfecho con la salida.

USE system_db_audits;
GO

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += 
    N'DROP TRIGGER ' + 
    QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + N'.' + 
    QUOTENAME(t.name) + N'; ' + NCHAR(13)
FROM sys.triggers AS t
WHERE t.is_ms_shipped = 0
  AND t.parent_class_desc = N'OBJECT_OR_COLUMN';

PRINT @sql;
Mark Sinkinson
fuente
5

Utilice la Sys.Triggerstabla de metadatos que contiene una fila para cada objeto que es un desencadenante

  1. Cambie el modo de salida a texto haciendo clic en el botón de la barra de herramientas que se muestra aquí:

ingrese la descripción de la imagen aquí

  1. Ejecute este script:

    USE YourDBName
    GO
    SELECT ' GO ' + Char(10) + Char(13) + 'DROP TRIGGER ' 
        + QUOTENAME(OBJECT_SCHEMA_NAME(O.[object_id])) + '.' 
        + QUOTENAME(name)
    FROM sys.sql_modules as M 
        INNER JOIN sys.triggers as O 
            ON M.object_id = O.object_id; 
  2. Copie el resultado en una nueva ventana de SQL Server Management Studio, verifique que el código realice las acciones que espera y ejecute.

AA.SC
fuente
Sin embargo, ¿las DROP TRIGGERdeclaraciones no necesitan terminadores ;?
ypercubeᵀᴹ
MSDN dice: Terminador de instrucciones Transact-SQL. Aunque el punto y coma no es necesario para la mayoría de las declaraciones en esta versión de SQL Server, será necesario en una versión futura.
AA.SC
2

En caso de que desee ejecutar un trabajo sql en un servidor central [ServerA] para realizar el trabajo de eliminación de activadores, le proporcionaré una versión de PowerShell suponiendo que tenga una instancia de SQL Server 2012 (o superior) con el módulo SQLPS instalado en [ServerA]

Supongamos que desea eliminar todos los desencadenantes en la base de datos [AdventureWorks] en la instancia de [ServerB] SQL Server (SQL Server 2005+).

Puede ejecutar la siguiente PS en [ServerA]:

import-module sqlps -DisableNameChecking;
$db=get-item -Path "sqlserver:\sql\ServerB\default\databases\AdventureWorks";

#before deletion, you can check that triggers do exist
$db.tables.triggers | select name

#now delete
$db.tables.triggers |Where-Object {-not $_.IsSystemObject } | foreach-object {$_.drop()};

#check after deletion
$db.tables.triggers | select name;

Recuerde reemplazar ServerB y AdventureWorks con sus propios valores.

Esta es una solución bastante flexible que puede personalizar fácilmente para adaptarla a otros requisitos diferentes, como que solo los desencadenantes de eliminación pertenecen a un conjunto específico de tablas, o deshabilitar (en lugar de eliminar) algunos desencadenantes específicos, etc.

Estrictamente hablando, las soluciones proporcionadas por @Mark Sinkinson no son correctas porque el requisito no es eliminar los desencadenantes en 'system_db_audits' db, sino eliminar los desencadenantes en otra base de datos de 'system_db_audits'. Esto significa que debe crear un sql dinámico en 'system_db_audits' para ajustar el "sql dinámico" proporcionado por @Mark Sinkinson para eliminar esos desencadenantes de destino, suponiendo que tanto 'system_db_audits' como el db de destino estén en la misma instancia de servidor sql. De lo contrario, si los dos dbs no están en la misma instancia, será incluso mucho "feo" manejar la eliminación (como a través de un servidor vinculado, etc.). En tal escenario, PS es una solución elegante, sin importar dónde esté o no el db objetivo en la misma instancia sql.

jyao
fuente