2012-08-27 18 views
70

अन्य उदाहरणों को देखकर मैं निम्नलिखित के साथ आया हूं लेकिन ऐसा लगता है कि यह काम नहीं करता है: मैं चाहता हूं कि यह केवल संशोधित जानकारी को अपडेट करे यदि QtyToRepair मूल्य अद्यतन किया गया है ... लेकिन यह ऐसा नहीं करता है।एसक्यूएल अपडेट केवल तभी ट्रिगर होता है जब कॉलम संशोधित होता है

यदि मैं टिप्पणी करता हूं कि संशोधित जानकारी प्रत्येक मामले में कहां अपडेट की जाती है। जैसा कि मैंने कहा कि अन्य उदाहरणों ने मुझे आशावादी बना दिया। किसी भी सुराग की सराहना की। धन्यवाद।

वाल्टर

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified] 
    ON [dbo].[SCHEDULE] 
    AFTER UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    UPDATE SCHEDULE SET modified = GETDATE() 
     , ModifiedUser = SUSER_NAME() 
     , ModifiedHost = HOST_NAME() 
    FROM SCHEDULE S 
    INNER JOIN Inserted I on S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber 
    WHERE S.QtyToRepair <> I.QtyToRepair 
END 
+1

क्या डीबी प्रयोग कर रहे हैं? –

+1

एसक्यूएल सर्वर की तरह loooks –

+7

'अद्यतन()' के बारे में एक चेतावनी - यह केवल तभी परीक्षण करता है जब कॉलम अद्यतन सूची में दिखाई देता है, और हमेशा आवेषण के लिए सच है। यह जांच नहीं करता है कि कॉलम मान बदल गया है, क्योंकि आपके पास एक से अधिक पंक्ति हो सकती है, जहां कुछ मान बदल गए हैं और कुछ नहीं हैं। –

उत्तर

93

अपने प्रश्न के लिए दो रास्ता नहीं है।

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified] 
    ON [dbo].[SCHEDULE] 
    AFTER UPDATE 
AS BEGIN 
    SET NOCOUNT ON; 
    IF UPDATE (QtyToRepair) 
    BEGIN 
     UPDATE SCHEDULE 
     SET modified = GETDATE() 
      , ModifiedUser = SUSER_NAME() 
      , ModifiedHost = HOST_NAME() 
     FROM SCHEDULE S INNER JOIN Inserted I 
     ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber 
     WHERE S.QtyToRepair <> I.QtyToRepair 
    END 
END 

2- उपयोग सम्मिलित किया गया तालिका और नष्ट तालिका

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified] 
    ON [dbo].[SCHEDULE] 
    AFTER UPDATE 
AS BEGIN 
    SET NOCOUNT ON;  

    UPDATE SCHEDULE 
    SET modified = GETDATE() 
     , ModifiedUser = SUSER_NAME() 
     , ModifiedHost = HOST_NAME() 
    FROM SCHEDULE S 
    INNER JOIN Inserted I ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber 
    INNER JOIN Deleted D ON S.OrderNo = D.OrderNo and S.PartNumber = D.PartNumber     
    WHERE S.QtyToRepair <> I.QtyToRepair 
    AND D.QtyToRepair <> I.QtyToRepair 
END 

आप तालिका SCHEDULE और सेट नया मान को QtyToRepair स्तंभ के लिए अद्यतन आदेश का उपयोग करते हैं, अगर नया मान से एक में पुराने मूल्य के बराबर या बीच में शामिल हों बहु पंक्ति, समाधान 1 शेड्यूल तालिका में सभी अद्यतन पंक्ति अपडेट करें लेकिन समाधान 2 अपडेट केवल पंक्तियों को शेड्यूल करें जो पुराना मान नए मान के बराबर नहीं है।

+0

यह उल्लेख करने के लिए खेद है कि यह SQLServer था। मुझे हटाए गए टेबल का उपयोग करने की आवश्यकता थी। मैंने एक अलग टेबल (इतिहास बनाए रखने के लिए) लिखना समाप्त कर दिया। –

+5

दृष्टिकोण # 2 बेहतर है, अगर आप अपने ट्रिगर को आग लगाना नहीं चाहते हैं तो कॉलम को उसी मान में बदला जा रहा है। – Neolisk

+0

मुझे लगता है कि मुझे कुछ याद आ रहा है - लेकिन दृष्टिकोण # 1 काम नहीं करेगा, क्योंकि यह * अपडेट * के बाद है, इसलिए वर्तमान पंक्ति हमेशा डालने वाली पंक्ति के समान मूल्य रखती है। यदि आप अपडेट – Rob

5

आप निम्न कार्य करना चाहते हैं:

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified] 
    ON [dbo].[SCHEDULE] 
    AFTER UPDATE 
AS 
BEGIN 
SET NOCOUNT ON; 

    IF (UPDATE(QtyToRepair)) 
    BEGIN 
     UPDATE SCHEDULE SET modified = GETDATE() 
      , ModifiedUser = SUSER_NAME() 
      , ModifiedHost = HOST_NAME() 
     FROM SCHEDULE S 
     INNER JOIN Inserted I ON S.OrderNo = I.OrderNo AND S.PartNumber = I.PartNumber 
     WHERE S.QtyToRepair <> I.QtyToRepair 
    END 
END 

कृपया ध्यान दें कि इस ट्रिगर हर बार सक्रिय कर देगा आप स्तंभ कोई फर्क नहीं पड़ता अद्यतन करता है, तो मूल्य एक ही है या नहीं।

11

किसी को यह जांचना चाहिए कि QtyToRepair पहले अपडेट किया गया है या नहीं। अपने उत्प्रेरक में

1- उपयोग अद्यतन कमान:

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified] 
    ON [dbo].[SCHEDULE] 
    AFTER UPDATE 
AS 
BEGIN 
SET NOCOUNT ON; 
    IF UPDATE (QtyToRepair) 
    BEGIN 
     UPDATE SCHEDULE 
     SET modified = GETDATE() 
      , ModifiedUser = SUSER_NAME() 
      , ModifiedHost = HOST_NAME() 
     FROM SCHEDULE S INNER JOIN Inserted I 
      ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber 
     WHERE S.QtyToRepair <> I.QtyToRepair 
    END 
END 
10

FYI कोड मैं साथ समाप्त हो गया:

IF UPDATE (QtyToRepair) 
    begin 
     INSERT INTO tmpQtyToRepairChanges (OrderNo, PartNumber, ModifiedDate, ModifiedUser, ModifiedHost, QtyToRepairOld, QtyToRepairNew) 
     SELECT S.OrderNo, S.PartNumber, GETDATE(), SUSER_NAME(), HOST_NAME(), D.QtyToRepair, I.QtyToRepair FROM SCHEDULE S 
     INNER JOIN Inserted I ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber 
     INNER JOIN Deleted D ON S.OrderNo = D.OrderNo and S.PartNumber = D.PartNumber 
     WHERE I.QtyToRepair <> D.QtyToRepair 
end 
+1

मुझे यह सहायक पाया गया क्योंकि ** 2- ऊपर दिए गए उत्तर के बीच शामिल हों जिसका उपयोग कभी नहीं हुआ जहां मानदंड 'WHERE S.QtyToRepair <> I.QtyToRepair और D.QtyToRepair <> I.QtyToRepair' पहले मानदंडों के रूप में कभी भी फायरिंग/मेल नहीं खाता था - डाली गई तालिका हमेशा वास्तविक तालिका मान से मेल खाती थी। 'WHERE I.QtyToRepair <> D.QtyToRepair' का उपयोग करना मेरे लिए महत्वपूर्ण था। इसके अलावा 'अगर अद्यतन (फ़ील्ड)' कई ट्रिगर्स फायरिंग से मदद करता है। – Firegarden

संबंधित मुद्दे

 संबंधित मुद्दे