Как я могу отбросить все триггеры в одной базе данных?

17

У меня есть база данных с 104 триггерами, есть ли способ удалить все триггеры с помощью одной команды из одной базы данных с именем system_db_audits?

Мохамед Махюб
источник

Ответы:

29

Вы можете использовать Dynamic SQL и sys.triggersDMV для создания запроса, который вы можете выполнить.

is_ms_shippedисключает любые триггеры, которые были отправлены с SQL Server.
parent_class_descфильтры для триггеров уровня объекта, а не уровня базы данных.

Изменение PRINTАнь , EXECкак только вы счастливы с выходом.

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;
Марк Синкинсон
источник
5

Используйте Sys.Triggersтаблицу метаданных, которая содержит строку для каждого объекта, который является триггером

  1. Измените режим вывода на текст, нажав кнопку на панели инструментов, показанную здесь:

введите описание изображения здесь

  1. Выполните этот скрипт:

    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. Скопируйте вывод в новое окно SQL Server Management Studio, убедитесь, что код выполняет ожидаемые действия, и выполните.

AA.SC
источник
Разве DROP TRIGGERзаявлениям не нужны терминаторы ;?
ypercubeᵀᴹ
MSDN говорит: терминатор операторов Transact-SQL. Хотя точка с запятой не требуется для большинства операторов в этой версии SQL Server, она потребуется в будущей версии.
AA.SC
2

Если вы хотите запустить задание sql на центральном сервере [ServerA], чтобы выполнить работу по удалению триггера, я предоставлю версию PowerShell, предполагающую, что у вас есть экземпляр SQL Server 2012 (или выше) с модулем SQLPS, установленным на [ServerA]

Допустим, вы хотите удалить все триггеры в базе данных [AdventureWorks] на [ServerB] экземпляре SQL Server (SQL Server 2005+).

Вы можете запустить следующий PS на [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;

Пожалуйста, не забудьте заменить ServerB и AdventureWorks своими собственными значениями.

Это довольно гибкое решение, которое вы можете легко настроить для адаптации к другим различным требованиям, например, только триггеры удаления принадлежат к определенному набору таблиц или отключить (вместо удаления) некоторые конкретные триггеры и т. Д.

Строго говоря, решения, предоставленные @Mark Sinkinson, неверны, поскольку требуется не удалять триггеры в базе данных «system_db_audits», а удалять триггеры в другой базе данных из «system_db_audits». Это означает, что вам нужно создать динамический sql в 'system_db_audits', чтобы обернуть "динамический sql", предоставленный @Mark Sinkinson, для удаления этих целевых триггеров, предполагая, что и system_db_audits, и целевой db находятся на одном экземпляре сервера sql. В противном случае, если две базы данных находятся не в одном и том же экземпляре, обработка удаления будет даже «уродливой» (например, через связанный сервер и т. Д.). В таком сценарии PS является элегантным решением, независимо от того, где находится или нет целевой базы данных в одном экземпляре SQL.

jyao
источник