2011-12-14 12 views
15

हटाएं, अपडेट करें, हटाएं के लिए मूल्य को कैसे पढ़ा जाए, मेरे पास एक तालिका में ट्रिगर है और जब कोई पंक्ति डाली जाती है, अपडेट या हटा दी जाती है तो UserId मान पढ़ना चाहेंगे। उसको कैसे करे? नीचे दिए गए कोड काम नहीं करता, मैं UPDATEDSQL सर्वर:

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
    ON [dbo].[Order] 
    AFTER INSERT,UPDATE,DELETE 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE 
    @UserId INT, 

    SELECT @UserId = INSERTED.UserId FROM INSERTED, DELETED 

    UPDATE dbo.[User] SET CreditsLeft = CreditsLeft - 1 WHERE Id = @UserId 
END 
+4

यह * भी * गलत है क्योंकि इन तालिकाओं में कई पंक्तियां हो सकती हैं, इसलिए एक चर में मान पढ़ने की कोशिश करने से आप उन पंक्तियों के मूल्यों में से एक (जो एक अनिर्धारित है) प्रदान करेगा। –

+1

एक त्रिभुज लिखने के अलावा जो सोचता है कि केवल एक पंक्ति बदली जाएगी जो एक खराब अभ्यास है, आपने अंतर्निहित जोड़ों का उपयोग किया है जो एक एसक्यूएल एंटीपाटर भी है। कभी भी अंतर्निहित जॉइन का उपयोग न करें। अभी आप उस क्रॉस में शामिल हो गए हैं जिसे आप शायद नहीं चाहते थे।शामिल होने के लगभग 20 साल बाद इस तरह के कोड को लिखने में असमर्थ है, जो कि बेहतर स्पष्ट रूप से स्पष्ट रूप से शामिल हो गए थे। – HLGEM

उत्तर

24

कृपया ध्यान दें कि inserted, deleted का अर्थ inserted CROSS JOIN deleted जैसा है और प्रत्येक पंक्ति के प्रत्येक संयोजन को देता है। मुझे संदेह है कि आप यही चाहते हैं।

कुछ इस तरह मदद कर सकते हैं आप कार्य आरंभ कर ...

SELECT 
    CASE WHEN inserted.primaryKey IS NULL THEN 'This is a delete' 
     WHEN deleted.primaryKey IS NULL THEN 'This is an insert' 
             ELSE 'This is an update' 
    END as Action, 
    * 
FROM 
    inserted 
FULL OUTER JOIN 
    deleted 
    ON inserted.primaryKey = deleted.primaryKey 


कि आप क्या करना चाहते हैं पर निर्भर करता है, तो आप तालिका को देख आप inserted.userID या deleted.userID, आदि के साथ में रुचि रखते हैं ।


अंत में, ध्यान रखें कि inserted और deletedतालिका हैं और (और करें) में एक से अधिक रिकॉर्ड हो सकते हैं।

यदि आप एक बार में 10 रिकॉर्ड डालते हैं, तो inserted तालिका में सभी 10 रिकॉर्ड होंगे। यह deletes और deleted तालिका पर लागू होता है। और एक अद्यतन के मामले में दोनों टेबल।


संपादित Examplee उत्प्रेरक के बाद ऑप्स संपादित करें।

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
    ON [dbo].[Order] 
    AFTER INSERT,UPDATE,DELETE 
AS 
BEGIN 

    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    UPDATE 
    User 
    SET 
    CreditsLeft = CASE WHEN inserted.UserID IS NULL THEN <new value for a DELETE> 
         WHEN deleted.UserID IS NULL THEN <new value for an INSERT> 
                ELSE <new value for an UPDATE> 
        END 
    FROM 
    User 
    INNER JOIN 
    (
     inserted 
    FULL OUTER JOIN 
     deleted 
     ON inserted.UserID = deleted.UserID -- This assumes UserID is the PK on UpdateUserCreditsLeft 
    ) 
     ON User.UserID = COALESCE(inserted.UserID, deleted.UserID) 

END 


UpdateUserCreditsLeft की PrimaryKey UserID के अलावा कुछ है, तो का उपयोग करें कि पूर्ण बाहरी में बजाय शामिल हों।

+1

महान जवाब, इसने आज अपना काम बचाया – wondergoat77

20

पर त्रुटि मिलती है कोई updated गतिशील तालिका नहीं है। केवल inserted और deleted है। UPDATE कमांड पर, पुराना डेटा deleted गतिशील तालिका में संग्रहीत है, और नए मान inserted गतिशील तालिका में संग्रहीत हैं।

DELETE/INSERT संयोजन के रूप में सोचें।

CREATE TRIGGER trigger_name 
ON { table | view } 
[ WITH ENCRYPTION ] 
{ 
    { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } 
     [ WITH APPEND ] 
     [ NOT FOR REPLICATION ] 
     AS 
     [ { IF UPDATE (column) 
      [ { AND | OR } UPDATE (column) ] 
       [ ...n ] 
     | IF (COLUMNS_UPDATED () { bitwise_operator } updated_bitmask) 
       { comparison_operator } column_bitmask [ ...n ] 
     } ] 
     sql_statement [ ...n ] 
    } 
} 

आप अद्यतन पर उपयोग करना चाहते हैं तो आप केवल IF UPDATE (column) अनुभाग के साथ यह कर सकते हैं:

+0

मैंने लाइन को बदल दिया है @UserId = उपयोगकर्ता आईडी से सम्मिलित, हटा दिया गया है और अब मुझे त्रुटि मिलती है संदिग्ध कॉलम नाम 'UserId'। – Tomas

+1

@ टॉमस - मेरा जवाब देखें, मुझे नहीं लगता ',' इसका मतलब है कि इसका मतलब क्या है। – MatBailie

+0

@ टॉमस आपको 'UserId' फ़ील्ड का स्रोत निर्दिष्ट करने की आवश्यकता है। उदाहरण के लिए, कुछ ऐसा करें जैसे '@UserId = inserted.UserId डालने से हटाएं, हटाए गए –

-4

यहाँ एक ट्रिगर बनाने के लिए वाक्य रचना है। जो भी आप पूछ रहे हैं वह करना संभव नहीं है।