2010-12-08 17 views
8

में कोई सम्मिलित, अद्यतन, हटाई गई पंक्ति की प्रतिलिपि कैसे करें यदि कोई उपयोगकर्ता HelloWorlds तालिका बदलता है, तो मैं चाहता हूं कि 'कार्रवाई उन्होंने किया', समय उन्होंने किया, और मूल पंक्ति डालने की एक प्रति HelloWorldsHistory में।SQL सर्वर ट्रिगर (0)

मैं कॉलम की लंबाई के कारण कार्रवाइयों को सम्मिलित करने, अपडेट करने और हटाने के लिए अलग ट्रिगर से बचना पसंद करूंगा।

मैं इस की कोशिश की है:

create trigger [HelloWorlds_After_IUD] on [HelloWorlds] 
FOR insert, update, delete 
as 
if @@rowcount = 0 
return 
if exists (select 1 from inserted) and not exists (select 1 from deleted) 
begin 
insert into HelloWorldHistory (hwh_action, ..long column list..) 
select 'INSERT', helloWorld.id, helloWorld.text ... and more from inserted 
end 
else 
    if exists (select 1 from inserted) and exists (select 1 from deleted) 
    begin 
insert into HelloWorldHistory (hwh_action, ..long column list..) 
select 'UPDATE', helloWorld.id, helloWorld.text ... and more from deleted 
    end 
    else 
    begin 
insert into HelloWorldHistory (hwh_action, ..long column list..) 
select 'DELETE', helloWorld.id, helloWorld.text ... and more from deleted 
    end 
end 

मैं एक डालने दिखाई कभी नहीं देखा है, लेकिन मैं अद्यतन देखा है। मैं 3 अलग ट्रिगर करने की कोशिश करने जा रहा हूं, हालांकि कॉलम सूचियों को बनाए रखना मजेदार नहीं होगा।

+0

UPDATE के लिए डेटा के स्रोत के रूप में हटाए गए उपयोग का उपयोग नहीं करते हैं, तो आप पहले से रिकॉर्ड किए गए पिछले मान को लॉग कर देंगे। आपकी लॉग पंक्ति "अपडेट" प्रकार होगी लेकिन डेटा एक सम्मिलन से हो सकता था। मुझे मेरे जवाब में टिप्पणी देखें। –

उत्तर

19

कुछ इस तरह का प्रयास करें:

CREATE TRIGGER YourTrigger ON YourTable 
    AFTER INSERT,UPDATE,DELETE 
AS 

DECLARE @HistoryType char(1) --"I"=insert, "U"=update, "D"=delete 

SET @HistoryType=NULL 

IF EXISTS (SELECT * FROM INSERTED) 
BEGIN 
    IF EXISTS (SELECT * FROM DELETED) 
    BEGIN 
     --UPDATE 
     SET @HistoryType='U' 
    END 
    ELSE 
    BEGIN 
     --INSERT 
     SET @HistoryType='I' 
    END 
    --handle insert or update data 
    INSERT INTO YourLog 
      (ActionType,ActionDate,.....) 
     SELECT 
      @HistoryType,GETDATE(),..... 
      FROM INSERTED 

END 
ELSE IF EXISTS(SELECT * FROM DELETED) 
BEGIN 
    --DELETE 
    SET @HistoryType='D' 

    --handle delete data, insert into both the history and the log tables 
    INSERT INTO YourLog 
      (ActionType,ActionDate,.....) 
     SELECT 
      @HistoryType,GETDATE(),..... 
      FROM DELETED 

END 
--ELSE 
--BEGIN 
-- both INSERTED and DELETED are empty, no rows affected 
--END 
+0

अच्छा काम करता है। पिछले कुछ वर्षों से ओरेकल में होने के बाद मुझे अपने धूलदार एमएस एसक्यूएल कौशल को खोदने के बारे में बहुत अच्छा महसूस हुआ। – DefyGravity

+0

मेरा अंत समाधान यह "आर्किटेक्चर" होगा, बॉब के पीके कॉलम स्रोत तालिका और अस्थायी लेनदेन ट्रिगर टेबल के बीच जांच करेंगे। साथ ही, मैं हटाए गए तालिका से 'अद्यतन' डेटा खींच रहा हूं, जैसा कि सम्मिलित है। – DefyGravity

+4

मैं दृढ़ता से अनुशंसा करता हूं कि आप INSERTED तालिका से अद्यतन लॉग करें। यहां एक उदाहरण दिया गया है: पंक्ति डेटा = एएए डालें (INSERTED = एएए लॉग करने के लिए चला जाता है), बीबीबी को उसी पंक्ति को अपडेट करें (INSERTED = BBB, DELETED = AAA, मैं कहता हूं कि लॉग इन करने के लिए बीबीबी भेजें, और एएए नहीं, जो पहले से रिकॉर्ड किया गया था)। साथ ही, 'IF EXISTS' का उपयोग करते समय, सभी "कुंजी जांच" आवश्यक नहीं हैं और केवल ओवरहेड हैं। एक ट्रिगर केवल एक समय में एक कमांड, एक आईएनएसईआरटी या एक अद्यतन या डिलीट के लिए आग लग सकता है, इसलिए ऑपरेशन निर्धारित करने के लिए कुंजियों से मिलान करने की कोई आवश्यकता नहीं है। आपके पास एक ट्रिगर के भीतर एक INSERT डेटा के साथ मिश्रित एक अद्यतन डेटा कभी नहीं होगा। –

6

आप डाला जाता है और नष्ट कर दिया कॉलम में संबद्ध करने के लिए (मैच) पंक्तियों की जरूरत है। इस तरह कुछ बेहतर काम करना चाहिए।

create trigger [HelloWorlds_After_IUD] on [HelloWorlds] 
FOR insert, update, delete 
as 

insert into HeloWorldsHistory 
select 'INSERT', helloWorld.id, helloWorld.text ... and more 
from inserted 
where myKeyColumn not in (select myKeyColumn from deleted) 

insert into HeloWorldsHistory 
select 'DELETE', helloWorld.id, helloWorld.text ... and more 
from deleted 
where myKeyColumn not in (select myKeyColumn from inserted) 

insert into HeloWorldsHistory 
select 'UPDATE', helloWorld.id, helloWorld.text ... and more 
from inserted 
where myKeyColumn in (select myKeyColumn from deleted) 
+0

मैं निश्चित रूप से पीके पर मिलान करने जा रहा हूं! उस पकड़ के लिए धन्यवाद! – DefyGravity

+1

इस स्थिति में पीके जांच पर केएम की टिप्पणी देखें – DefyGravity