it-swarm.com.de

Wie kann ich alle Trigger in einer einzigen Datenbank ablegen?

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?

17
Mohamed Mahyoub

Sie können Dynamic SQL und das sys.triggers DMV zum Erstellen einer Abfrage, die Sie ausführen können.

is_ms_shipped schließt alle Trigger aus, die mit SQL Server ausgeliefert wurden.
parent_class_desc filtert eher nach Triggern auf Objektebene als nach Datenbankebene.

Ändern Sie das PRINT in ein EXEC, sobald 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;
30
Mark Sinkinson

Verwenden Sys.Triggers Metadatentabelle, die eine Zeile für jedes Objekt enthält, das ein Trigger ist

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

(enter image description here

  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 erwarteten Aktionen ausführt, und führen Sie sie aus.

5
AA.SC

Wenn Sie einen SQL-Job auf einem zentralen Server [ServerA] ausführen möchten, um die Trigger-Löscharbeiten auszuführen, werde ich eine PowerShell-Version bereitstellen, vorausgesetzt, Sie haben eine SQL Server 2012-Instanz (oder höher) mit auf [ServerA] installiertem SQLPS-Modul.

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

Sie können die 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 ziemlich flexible Lösung, die Sie leicht anpassen können, um sie an andere unterschiedliche Anforderungen anzupassen, z. B. dass nur Löschauslöser zu einem bestimmten Satz von Tabellen gehören oder bestimmte Auslöser deaktivieren (anstatt zu löschen) usw.

Genau genommen sind die von @Mark Sinkinson bereitgestellten Lösungen nicht korrekt, da die Anforderung nicht zum Löschen von Triggern in der Datenbank 'system_db_audits', aber zum Löschen von Triggern in einer anderen Datenbank von 'lautet. system_db_audits '. Dies bedeutet, dass Sie in 'system_db_audits' eine dynamische SQL erstellen müssen, um die von @Mark Sinkinson bereitgestellte "dynamische SQL" zu verpacken und diese Zielauslöser zu löschen, vorausgesetzt, dass sich sowohl 'system_db_audits' als auch die Ziel-Datenbank auf derselben SQL-Serverinstanz befinden. Andernfalls ist es sogar sehr "hässlich", die Löschung zu handhaben (z. B. über einen Verbindungsserver usw.), wenn sich die beiden Datenbankdateien nicht in derselben Instanz befinden. In einem solchen Szenario ist PS eine elegante Lösung, unabhängig davon, wo sich die Zieldatenbank auf derselben SQL-Instanz befindet oder nicht.

2
jyao