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?
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?
Respuestas:
Puede usar Dynamic SQL y el sys.triggers
DMV para crear consultas que puede ejecutar.
is_ms_shipped
excluye cualquier desencadenante que se envió con SQL Server.
parent_class_desc
filtros para disparadores a nivel de objeto, en lugar de nivel de base de datos.
Cambie PRINT
a una EXEC
vez 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;
Utilice la Sys.Triggers
tabla de metadatos que contiene una fila para cada objeto que es un desencadenante
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;
Copie el resultado en una nueva ventana de SQL Server Management Studio, verifique que el código realice las acciones que espera y ejecute.
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.
DROP TRIGGER
declaraciones no necesitan terminadores;
?