Як я можу скинути всі тригери в єдину базу даних?


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, перевірте, чи виконує код очікувані вами дії, і виконайте.


Невже 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, не є правильним, оскільки вимога полягає не в тому, щоб видаляти тригери на db 'system_db_audits' db, а видалити тригери в іншому db з 'system_db_audits'. Це означає, що вам потрібно створити динамічний sql у 'system_db_audits', щоб обернути "динамічний sql", наданий @Mark Sinkinson, щоб видалити ці цільові тригери, припускаючи, що і "system_db_audits", і цільовий db знаходяться на одному екземплярі сервера sql. Інакше, якщо два dbs не знаходяться в одному екземплярі, це буде навіть набагато "потворно" обробляти видалення (наприклад, через пов'язаний сервер тощо). У такому сценарії PS - це елегантне рішення незалежно від того, де цільовий db знаходиться чи не знаходиться в одному екземплярі sql.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.