จะเปลี่ยนลำดับการยิงของ Triggers ได้อย่างไร?


12

จริงๆฉันไม่ค่อยใช้ทริกเกอร์ ดังนั้นฉันจึงพบปัญหาในครั้งแรก ฉันมีตารางจำนวนมากที่มีทริกเกอร์ (2 หรือมากกว่าสำหรับทุกตาราง) ฉันต้องการทราบและเปลี่ยนลำดับการเรียกทริกเกอร์สำหรับทุกตาราง เป็นไปได้หรือไม่ที่จะได้รับข้อมูลนี้?

เพิ่ม:

นี่คือบทความ enoght ที่ดีใน mssqltipsฉันได้พบ

คำตอบ:


12

คุณสามารถใช้คำสั่งต่อไปนี้เพื่อแสดงรายการทริกเกอร์ทั้งหมดในแต่ละตาราง

EXEC sp_MSForEachTable 'PRINT ''?'' 
EXEC sp_helptrigger ''?'''

เมื่อคุณพบทริกเกอร์ทั้งหมด คุณสามารถเปลี่ยนลำดับด้วยตนเองโดยใช้ sp_settriggerorder

ข้อความแสดงแทน


2
"isafter" ไม่เพียง แต่ระบุว่าทริกเกอร์นั้นถูกกำหนดเป็น AFTER <action> แทนที่จะเป็น INSTEAD OF <action> แทนที่จะบอกอะไรเกี่ยวกับลำดับการดำเนินการของทริกเกอร์ประเภทเดียวกันสองตัวหรือมากกว่า
David Spillett

@ David - ใช่! คุณพูดถูก
CoderHawk

12

IIRC คุณไม่สามารถรับประกันได้ว่าคำสั่งที่ทริกเกอร์ (พร้อมคำจำกัดความของสิ่งที่จะตอบสนองและเมื่อใด) ยิงสำหรับการกระทำที่กำหนดกับตารางสำหรับจำนวนที่กำหนด

คุณสามารถทำได้ถ้ามีสามหรือน้อยกว่าเนื่องจากคุณสามารถใช้sp_settriggerorderเพื่อตั้งค่าแรกให้เป็นคนแรกคนสุดท้ายที่จะเป็นคนสุดท้ายและคนที่อยู่ตรงกลางจะมีคำสั่ง "ไม่ได้กำหนด"

หากทริกเกอร์ของคุณมีความไวต่อคำสั่งที่ดำเนินการในนี้มักจะบ่งบอกว่าการออกแบบของคุณมีความซับซ้อนมากกว่าที่จะต้อง (มักจะเกิดจากการเติบโตอินทรีย์) และอาจได้รับประโยชน์จากการปรับโครงสร้างบางอย่าง


+1 คุณถูกต้องฉันต้องสร้างรหัสนี้ใหม่ (มันซับซ้อนและมีลิงก์ข้าม ... ) แต่ฉันอยู่ในขั้นตอนแรก - การสอบสวน
garik

5
-- List tables with triggers and their firing order.  By Jackson Jarvis.
SELECT [tbl].[name] AS 'Table'
      ,[trg].[name] AS 'Trigger'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete Last'
  FROM            [sysobjects] AS [trg] WITH (NOLOCK)
       INNER JOIN [sysobjects] AS [tbl] WITH (NOLOCK)
            ON  [trg].[parent_obj] = [tbl].[id]
  WHERE [trg].[TYPE] IN (N'TR')
  ORDER BY
       [tbl].[name] ASC
      ,[trg].[name] ASC
  ;

1
มันดูเนียนดี @garik สิ่งนี้ทำงานกับสภาพแวดล้อมของคุณหรือไม่ (BTW ความคิดเห็นเริ่มต้นของ SQL ควรเป็นส่วนหนึ่งของบล็อคโค้ดด้วย)
Nick Chammas

1
@ ไม่เป็นไร ฉันมองไปรอบ ๆ ไม่กี่นาที
garik

@Nick ตามค่าเริ่มต้นคุณสมบัติเหล่านี้จะว่างเปล่า ดังนั้นหากดำเนินการตัวอย่างเช่น exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'เราสามารถเห็นผลลัพธ์ ('X') ในผลการสืบค้นของแจ็คสัน ขอบคุณแจ็กสัน
garik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.