ฉันจะวางทริกเกอร์ทั้งหมดในฐานข้อมูลเดียวได้อย่างไร


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.TriggersMeta Data Table ซึ่งมีแถวสำหรับแต่ละวัตถุที่เป็นทริกเกอร์

  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 ตรวจสอบว่ารหัสดำเนินการตามที่คุณต้องการและดำเนินการ


ข้อความเหล่านั้นไม่DROP TRIGGERจำเป็นต้องมี terminators ;ใช่ไหม
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' db แต่เพื่อลบทริกเกอร์ใน db อื่นจาก 'system_db_audits' ซึ่งหมายความว่าคุณต้องสร้าง sql แบบไดนามิกใน 'system_db_audits' เพื่อตัด "ไดนามิก sql" ที่มีให้โดย @Mark Sinkinson เพื่อลบทริกเกอร์เป้าหมายเหล่านั้นโดยสมมติว่าทั้ง 'system_db_audits' และ db เป้าหมายอยู่ในอินสแตนซ์เซิร์ฟเวอร์ sql เดียวกัน มิฉะนั้นหากทั้งสอง dbs ไม่ได้อยู่ในอินสแตนซ์เดียวกันมันจะยิ่ง "น่าเกลียด" มากขึ้นในการจัดการการลบ (เช่นผ่านทางเซิร์ฟเวอร์ที่เชื่อมโยง ฯลฯ ) ในสถานการณ์ดังกล่าว PS เป็นโซลูชันที่สวยงามไม่ว่าฐานข้อมูลเป้าหมายจะอยู่หรือไม่อยู่ในอินสแตนซ์ของ sql เดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.