Como posso eliminar todos os gatilhos em um único banco de dados?

17

Eu tenho um banco de dados com 104 gatilhos, existe uma maneira de excluir todos os gatilhos com um único comando de um único banco de dados chamado 'system_db_audits?

Mohamed Mahyoub
fonte

Respostas:

29

Você pode usar o SQL dinâmico e o sys.triggersDMV para criar a consulta que você pode executar.

is_ms_shippedexclui todos os gatilhos que foram enviados com o SQL Server.
parent_class_descfiltros para acionadores no nível do objeto, em vez do nível do banco de dados.

Altere PRINTpara para EXECquando estiver satisfeito com a saída.

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

Use a Sys.Triggerstabela de metadados que contém uma linha para cada objeto que é um acionador

  1. Altere o modo de saída para texto clicando no botão da barra de ferramentas mostrado aqui:

insira a descrição da imagem aqui

  1. Execute 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; 
  2. Copie Saída para uma nova janela do SQL Server Management Studio, verifique se o código executa as ações que você espera e Execute.

AA.SC
fonte
As DROP TRIGGERdeclarações não precisam de terminadores ;?
precisa saber é o seguinte
O MSDN diz: Terminador de instruções Transact-SQL. Embora o ponto-e-vírgula não seja necessário para a maioria das instruções nesta versão do SQL Server, será necessário em uma versão futura.
AA.SC
2

Caso você deseje executar um trabalho sql em um servidor central [ServerA] para executar o trabalho de exclusão de gatilhos, fornecerei uma versão do PowerShell assumindo que você tenha uma instância do SQL Server 2012 (ou superior) com o módulo SQLPS instalado no [ServerA]

Digamos que você queira excluir todos os gatilhos no banco de dados [AdventureWorks] na instância do [ServerB] SQL Server (SQL Server 2005+).

Você pode executar o seguinte PS no [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;

Lembre-se de substituir o ServerB e o AdventureWorks por seus próprios valores.

Essa é uma solução bastante flexível que você pode personalizar facilmente para se adaptar a outros requisitos diferentes, como apenas os gatilhos de exclusão pertencem a um conjunto específico de tabelas ou desabilitar (em vez de excluir) alguns gatilhos específicos etc.

A rigor, as soluções fornecidas pelo @Mark Sinkinson não estão corretas porque o requisito não é excluir gatilhos no banco de dados 'system_db_audits', mas excluir gatilhos em outro banco de dados de 'system_db_audits'. Isso significa que você precisa criar um sql dinâmico em 'system_db_audits' para agrupar o "sql dinâmico" fornecido pelo @Mark Sinkinson para excluir os gatilhos de destino, assumindo que ambos 'system_db_audits' e o db de destino estejam na mesma instância do servidor sql. Caso contrário, se os dois dbs não estiverem na mesma instância, será muito "feio" lidar com a exclusão (como por meio do servidor vinculado etc.). Nesse cenário, o PS é uma solução elegante, não importa onde o banco de dados de destino esteja ou não na mesma instância sql.

jyao
fonte