Wie kann ich alle Trigger in einer einzigen Datenbank löschen?

17

Ich habe eine Datenbank mit 104 Triggern. Gibt es eine Möglichkeit, alle Trigger mit einem einzigen Befehl aus einer einzigen Datenbank mit dem Namen 'system_db_audits' zu löschen?

Mohamed Mahyoub
quelle

Antworten:

29

Sie können Dynamic SQL und sys.triggersDMV verwenden, um eine Abfrage zu erstellen, die Sie ausführen können.

is_ms_shippedSchließt alle Trigger aus, die mit SQL Server ausgeliefert wurden.
parent_class_descFilter für Trigger auf Objektebene anstatt auf Datenbankebene.

Wechseln Sie PRINTzu, EXECsobald Sie mit der Ausgabe zufrieden sind.

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
quelle
5

Verwenden Sie die Sys.TriggersMetadatentabelle, die eine Zeile für jedes Objekt enthält, das ein Auslöser ist

  1. Ändern Sie den Ausgabemodus in Text, indem Sie auf die hier gezeigte Schaltfläche in der Symbolleiste klicken:

Bildbeschreibung hier eingeben

  1. Führen Sie dieses Skript aus:

    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. Kopieren Sie die Ausgabe in ein neues SQL Server Management Studio-Fenster, überprüfen Sie, ob der Code die von Ihnen erwarteten Aktionen ausführt, und führen Sie sie aus.

AA.SC
quelle
Benötigen die DROP TRIGGERAnweisungen jedoch keine Abschlusszeichen ;?
Ypercubeᵀᴹ
MSDN sagt: Transact-SQL-Anweisungsterminator. Obwohl das Semikolon für die meisten Anweisungen in dieser Version von SQL Server nicht erforderlich ist, wird es in einer zukünftigen Version benötigt.
AA.SC
2

Für den Fall, dass Sie einen SQL-Auftrag auf einem zentralen Server [ServerA] ausführen möchten, um die Löscharbeiten für den Auslöser auszuführen, stelle ich eine PowerShell-Version zur Verfügung, vorausgesetzt, Sie haben eine SQL Server 2012-Instanz (oder höher) mit einem auf [ServerA] installierten SQLPS-Modul.

Angenommen, Sie möchten alle Trigger in der [AdventureWorks] -Datenbank auf der SQL Server-Instanz [ServerB] (SQL Server 2005+) löschen.

Sie können das folgende PS auf [ServerA] ausführen:

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;

Bitte denken Sie daran, ServerB und AdventureWorks durch Ihre eigenen Werte zu ersetzen .

Dies ist eine recht flexible Lösung, die Sie leicht anpassen können, um sie an andere Anforderungen anzupassen, z.

Genau genommen sind die von @Mark Sinkinson bereitgestellten Lösungen nicht korrekt, da die Anforderung nicht darin besteht , Trigger in 'system_db_audits' db zu löschen, sondern Trigger in einer anderen Datenbank aus 'system_db_audits' zu löschen . Dies bedeutet, dass Sie eine dynamische SQL in 'system_db_audits' erstellen müssen, um die von @Mark Sinkinson bereitgestellten "dynamischen SQL" zu verpacken und diese Ziel-Trigger zu löschen, vorausgesetzt, dass sich sowohl 'system_db_audits' als auch die Ziel-DB auf derselben SQL-Server-Instanz befinden. Andernfalls, wenn sich die beiden Datenbanken nicht auf derselben Instanz befinden, ist es sogar sehr "hässlich", mit dem Löschen umzugehen (z. B. über einen Verbindungsserver usw.). In einem solchen Szenario ist PS eine elegante Lösung, unabhängig davon, wo sich die Ziel-DB auf derselben SQL-Instanz befindet oder nicht.

jyao
quelle