web-dev-qa-db-fra.com

Comment puis-je supprimer tous les déclencheurs dans une seule base de données?

J'ai une base de données avec 104 déclencheurs, existe-t-il un moyen de supprimer tous les déclencheurs avec une seule commande d'une seule base de données appelée 'system_db_audits?

17
Mohamed Mahyoub

Vous pouvez utiliser Dynamic SQL et le sys.triggers DMV pour construire une requête que vous pouvez exécuter.

is_ms_shipped exclut tous les déclencheurs fournis avec SQL Server.
parent_class_desc filtres pour les déclencheurs au niveau objet, plutôt qu'au niveau base de données.

Remplacez PRINT par EXEC une fois que vous êtes satisfait de la sortie.

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;
30
Mark Sinkinson

Utilisation Sys.Triggers Table de métadonnées qui contient une ligne pour chaque objet qui est un déclencheur

  1. Changez le mode de sortie en texte en cliquant sur le bouton de la barre d'outils illustré ici:

enter image description here

  1. Exécutez ce 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. Copiez la sortie dans une nouvelle fenêtre SQL Server Management Studio, vérifiez que le code exécute les actions que vous attendez et exécutez.

5
AA.SC

Dans le cas où vous souhaitez exécuter un travail SQL sur un serveur central [ServerA] pour effectuer le travail de suppression du déclencheur, je fournirai une version PowerShell en supposant que vous avez une instance SQL Server 2012 (ou supérieure) avec le module SQLPS installé sur [ServerA]

Supposons que vous souhaitiez supprimer tous les déclencheurs de la base de données [AdventureWorks] sur l'instance de [ServerB] SQL Server (SQL Server 2005+).

Vous pouvez exécuter le PS suivant sur [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;

N'oubliez pas de remplacer ServerB et AdventureWorks par vos propres valeurs.

Il s'agit d'une solution assez flexible que vous pouvez facilement personnaliser pour l'adapter à d'autres exigences différentes, telles que seuls les déclencheurs de suppression appartiennent à un ensemble spécifique de tables, ou désactivez (au lieu de supprimer) certains déclencheurs spécifiques, etc.

À strictement parler, les solutions fournies par @Mark Sinkinson ne sont pas correctes car l'exigence est pas pour supprimer les déclencheurs sur la base de données 'system_db_audits', mais pour supprimer les déclencheurs dans une autre base de données de ' system_db_audits '. Cela signifie que vous devez créer un SQL dynamique dans 'system_db_audits' pour encapsuler le "SQL dynamique" fourni par @Mark Sinkinson pour supprimer ces déclencheurs cibles en supposant que 'system_db_audits' et la base de données cible se trouvent sur la même instance de serveur SQL. Sinon, si les deux dbs ne sont pas sur la même instance, il sera même beaucoup "moche" de gérer la suppression (comme via un serveur lié, etc.). Dans un tel scénario, PS est une solution élégante, peu importe où la base de données cible se trouve ou non sur la même instance SQL.

2
jyao