2012-02-18 19 views
5

के साथ फ़ील्ड को अपडेट करने के लिए कैसे मैं उसी तालिका में एक फ़ील्ड अपडेट करना चाहता हूं जिसमें रिकॉर्ड हटाया जा रहा है लेकिन यह भी सुनिश्चित नहीं है कि कैसे। तालिका बहुत सरल है और उस पर एक आत्म संदर्भ है:SQL सर्वर 2008 - DELETE ट्रिगर

UserID FName EmailAddress EmailUserID 
1   Frank [email protected] 2 
2   Jane [email protected] NULL 
3   John [email protected] 1 
4   Brett [email protected] 2 

यहाँ मेरी ट्रिगर है:

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    WHERE EmailUserID = ID_OF_DELETED_USER <-- don't know how to get this 

END 

तो अगर मैं जेन (UserID = 2) हटाने के लिए, मैं अद्यतन करने के लिए ट्रिगर करना चाहते हैं ईमेलयूसर आईडी के साथ कोई रिकॉर्ड 2. मैं इसे कैसे पूरा कर सकता हूं?

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    WHERE EmailUserID IN (SELECT UserID FROM DELETED) 

END 
+0

आप जानते हैं कि यह केवल तभी काम करेगा यदि आपके पास * एक आत्म-संदर्भित विदेशी कुंजी नहीं है, है ना? जिसका अर्थ है कि आप EmailUserID में कोई भी मूल्य डाल सकते हैं और SQL सर्वर शिकायत नहीं करेगा। –

उत्तर

3

ध्यान दें कि अगर आप उचित FOREIGN KEY बाधा के साथ तालिका सेट अप करें, एक ट्रिगर के बाद नौकरी करने वाला नहीं है। DELETE ट्रिगर में आपरेशन से पहले तार्किक होता है, ताकि आप मिल जाएगा:

Msg 547, Level 16, State 0, Line 2 
The DELETE statement conflicted with the SAME TABLE REFERENCE constraint ... 

तो अगर आप डेटा अखंडता चाहते हैं, ताकि कोई भी EMailUserID स्तंभ में कचरा सामान कर सकते हैं, तो आप एक INSTEAD OF ट्रिगर का उपयोग कर सकते इस प्रकार है:

CREATE TABLE dbo.Users 
(
    UserID INT NOT NULL PRIMARY KEY, 
    FName NVARCHAR(32), 
    EmailAddress VARCHAR(320), 
    EmailUserID INT NULL FOREIGN KEY REFERENCES dbo.Users(UserID) 
); 
GO 

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
ON dbo.Users 
INSTEAD OF DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    -- clean up references first 
    UPDATE u SET u.EmailUserID = NULL 
     FROM dbo.Users AS u 
     INNER JOIN deleted AS d 
     ON u.EmailUserID = d.UserID; 

    -- now delete the row 
    DELETE u 
    FROM dbo.Users AS u 
    INNER JOIN deleted AS d 
    ON u.UserID = d.UserID; 
END 
GO 

नमूना है, तो इस चलाने) dbo.Users की एक प्रति tempdb में, इसके बाद के संस्करण के रूप में, बनाने की कोशिश:

INSERT dbo.Users(UserID, FName, EmailAddress, EmailUserID) VALUES 
(1,'Frank','[email protected]',2 ), 
(2,'Jane ','[email protected] ',NULL), 
(3,'John ','[email protected] ',1 ), 
(4,'Brett','[email protected]',2 ); 

SELECT * FROM dbo.Users; 
GO 

DELETE dbo.Users WHERE UserID = 2; 
GO 

SELECT * FROM dbo.Users; 
GO 

DROP TABLE dbo.Users; 
GO 
2

क्षमा करें, प्रश्न गलत पहली बार ... ट्रिगर के बाद एक इस मामले में संभव है मिल गया

CREATE TRIGGER [dbo].[CAT_DeleteUser] ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    FROM Users 
    JOIN DELETED 
     ON Users.EmailUserID = Deleted.UserID 

END 
+0

क्या आप इसे संक्षेप में बता सकते हैं? इसकी वजह से, यह उस उपयोगकर्ता तालिका को अपडेट करेगा जहां उपयोगकर्ता आईडी DELETE UserID है, जब तक कि आप कहां ईमेल यूज़र आईडी नहीं डालते (हटाए गए उपयोगकर्ता आईडी चुनें)। – Robert

+0

@Robert: यदि आप मूल हटाए गए कथन से पंक्ति प्रभावित करते हैं, तो आप उपयोगकर्ता तालिका को अपडेट करना चाहते हैं और कॉलम EmailUserID को शून्य पर सेट करना चाहते हैं, है ना? उपयोगकर्ता आईडी मानना ​​तालिका का पीके है, ट्रिगर सभी पंक्तियों में शून्य करने के लिए ईमेल यूज़र आईडी सेट करता है, जो मूल हटाए गए कथन द्वारा हटाए जाने के लिए थे। – Mithrandir

+0

मैंने यहां एक सुधार भी किया है। आप उस पंक्ति को अपडेट कर रहे थे जहां उपयोगकर्ता आईडी मेल खाते थे। मैं @ ओलेग से सहमत हूं आपको इस सवाल पर अधिक बारीकी से देखने की जरूरत है। –

7

के बाद आप का उपयोग कर सकते DELETE ट्रिगर::

+0

मैंने दो सुधार किए हैं। कोई आईडी कॉलम नहीं है; इसे UserID होने के लिए सही किया गया। इसमें शामिल होने के योग्य भी हैं क्योंकि ईमेल यूज़र आईडी दोनों उपयोगकर्ताओं में मौजूद है और हटा दिया गया है - यह अस्पष्ट कॉलम नाम के कारण पार्सिंग विफल होना चाहिए। –

+0

@AaronBertrand Thanx बहुत कुछ। –

+0

@ ओलेगोक: वास्तव में क्षमा करें, मुझे यह बहुत बुरी तरह गलत हो गया। – Mithrandir