Bagaimana saya bisa melepaskan semua pemicu dalam satu basis data?

17

Saya memiliki basis data dengan 104 pemicu, apakah ada cara untuk menghapus semua pemicu dengan satu perintah dari satu basis data yang disebut 'system_db_audits?

Mohamed Mahyoub
sumber

Jawaban:

29

Anda bisa menggunakan Dynamic SQL dan sys.triggersDMV untuk membangun kueri yang bisa Anda jalankan.

is_ms_shippedmengecualikan setiap pemicu yang dikirimkan dengan SQL Server.
parent_class_descfilter untuk pemicu tingkat objek, bukan tingkat basis data.

Ubah PRINTke EXECsekali Anda puas dengan hasilnya.

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

Gunakan Sys.TriggersTabel Data Meta yang berisi baris untuk setiap objek yang merupakan pemicu

  1. Ubah mode keluaran ke teks dengan mengklik tombol bilah alat yang ditampilkan di sini:

masukkan deskripsi gambar di sini

  1. Jalankan skrip ini:

    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. Salin Output ke jendela SQL Server Management Studio baru, verifikasi kode melakukan tindakan yang Anda harapkan, dan Jalankan.

AA.SC
sumber
Bukankah DROP TRIGGERpernyataan itu membutuhkan terminator ;?
ypercubeᵀᴹ
MSDN mengatakan: Terminator pernyataan SQL Transact. Meskipun titik koma tidak diperlukan untuk sebagian besar pernyataan dalam versi SQL Server ini, itu akan diperlukan dalam versi masa depan.
AA.SC
2

Jika Anda ingin menjalankan pekerjaan sql pada server pusat [ServerA] untuk melakukan pekerjaan penghapusan pemicu, saya akan memberikan versi PowerShell dengan asumsi Anda memiliki instance SQL Server 2012 (atau lebih tinggi) dengan modul SQLPS diinstal pada [ServerA]

Katakanlah Anda ingin menghapus semua pemicu dalam database [AdventureWorks] pada [ServerB] contoh SQL Server (SQL Server 2005+).

Anda dapat menjalankan PS berikut di [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;

Harap ingat untuk mengganti ServerB dan AdventureWorks dengan nilai Anda sendiri.

Ini adalah solusi yang cukup fleksibel yang dapat Anda sesuaikan dengan mudah untuk beradaptasi dengan persyaratan lain yang berbeda, seperti hanya menghapus pemicu yang dimiliki oleh seperangkat tabel tertentu, atau menonaktifkan (bukannya menghapus) beberapa pemicu tertentu dll.

Sebenarnya, solusi yang disediakan oleh @Mark Sinkinson tidak benar karena persyaratannya bukan untuk menghapus pemicu pada db 'system_db_audits', tetapi untuk menghapus pemicu pada db lain dari 'system_db_audits'. Ini berarti Anda perlu membuat sql dinamis di 'system_db_audits' untuk membungkus "sql dinamis" yang disediakan oleh @Mark Sinkinson untuk menghapus pemicu target tersebut dengan asumsi bahwa kedua 'system_db_audits' dan target db berada pada contoh server sql yang sama. Kalau tidak, jika dua dbs tidak pada contoh yang sama, itu akan menjadi jauh lebih "jelek" untuk menangani penghapusan (seperti melalui server yang terhubung dll). Dalam skenario seperti itu, PS adalah solusi elegan di mana pun target db berada atau tidak pada instance sql yang sama.

jyao
sumber