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

17

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?

Mohamed Mahyoub
la source

Réponses:

29

Vous pouvez utiliser Dynamic SQL et le sys.triggersDMV pour créer une requête que vous pouvez exécuter.

is_ms_shippedexclut tous les déclencheurs fournis avec SQL Server.
parent_class_descfiltres pour les déclencheurs au niveau de l'objet, plutôt qu'au niveau de la base de données.

Changez le PRINTen une EXECfois 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;
Mark Sinkinson
la source
5

Utilisez Sys.Triggersla 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:

entrez la description de l'image ici

  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.

AA.SC
la source
Les DROP TRIGGERdéclarations n'ont -elles pas besoin de terminateurs ;?
ypercubeᵀᴹ
MSDN indique: Terminateur d'instruction Transact-SQL. Bien que le point-virgule ne soit pas requis pour la plupart des instructions dans cette version de SQL Server, il le sera dans une future version.
AA.SC
2

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 [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 n'est pas de supprimer les déclencheurs sur la base de données 'system_db_audits', mais de 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 envelopper 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.

jyao
la source