Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

जब मैं डेटाबेस बाधाओं का उपयोग करना चाहता हूं लेकिन हटाने के बजाय केवल हटाए गए के रूप में चिह्नित करना चाहता हूं तो क्या करें?

जब कोई रिकॉर्ड हटा दिया जाता है तो आप आईडी मान को नाम के अंत में जोड़ सकते हैं, इसलिए जब कोई आईडी 3 हटाता है तो नाम Thingy3_3 हो जाता है और फिर जब वे आईडी 100 हटाते हैं तो नाम Thingy3_100 हो जाता है। यह आपको नाम और हटाए गए फ़ील्ड पर एक अद्वितीय समग्र अनुक्रमणिका बनाने की अनुमति देगा लेकिन जब भी आप इसे प्रदर्शित करते हैं तो आपको नाम कॉलम फ़िल्टर करना होगा और आईडी को नाम के अंत से हटा देना होगा।

शायद एक बेहतर उपाय यह होगा कि आप अपने हटाए गए कॉलम को DATETIME प्रकार के हटाए गए_at कॉलम से बदल दें। फिर आप नाम पर एक अद्वितीय अनुक्रमणिका बनाए रख सकते हैं और हटाए गए गैर-हटाए गए रिकॉर्ड के साथ हटाए गए_at फ़ील्ड में शून्य मान के साथ हटा दिया जा सकता है। यह सक्रिय अवस्था में कई नामों के निर्माण को रोकेगा लेकिन आपको एक ही नाम को कई बार हटाने की अनुमति देगा।

यह सुनिश्चित करने के लिए कि एक ही नाम के साथ कोई पंक्ति नहीं है और अन-डिलीट करने की अनुमति देने से पहले एक शून्य डिलीट_एट फ़ील्ड नहीं है, आपको स्पष्ट रूप से एक परीक्षण करने की आवश्यकता है।

आप वास्तव में डिलीट के लिए INSTEAD-OF ट्रिगर का उपयोग करके डेटाबेस के भीतर इस तर्क को लागू कर सकते हैं। जब आप कोई रिकॉर्ड हटाते हैं तो यह ट्रिगर रिकॉर्ड को नहीं हटाएगा, बल्कि हटाए गए_पर कॉलम को अपडेट करेगा।

निम्नलिखित उदाहरण कोड इसे प्रदर्शित करता है

CREATE TABLE swtest (  
    id          INT IDENTITY,  
    name        NVARCHAR(20),  
    deleted_at  DATETIME  
)  
GO  
CREATE TRIGGER tr_swtest_delete ON swtest  
INSTEAD OF DELETE  
AS  
BEGIN  
    UPDATE swtest SET deleted_at = getDate()  
    WHERE id IN (SELECT deleted.id FROM deleted)
    AND deleted_at IS NULL      -- Required to prevent duplicates when deleting already deleted records  
END  
GO  

CREATE UNIQUE INDEX ix_swtest1 ON swtest(name, deleted_at)  

INSERT INTO swtest (name) VALUES ('Thingy1')  
INSERT INTO swtest (name) VALUES ('Thingy2')  
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()  
INSERT INTO swtest (name) VALUES ('Thingy2')  
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()  
INSERT INTO swtest (name) VALUES ('Thingy2')  

SELECT * FROM swtest  
DROP TABLE swtest  

इस क्वेरी से चयन निम्नलिखित देता है

id      name       deleted_at
1       Thingy1    NULL
2       Thingy2    2009-04-21 08:55:38.180
3       Thingy2    2009-04-21 08:55:38.307
4       Thingy2    NULL

तो अपने कोड के भीतर आप सामान्य डिलीट का उपयोग करके रिकॉर्ड हटा सकते हैं और ट्रिगर को विवरणों का ध्यान रखने दें। एकमात्र संभावित मुद्दा (जो मैं देख सकता था) यह था कि पहले से हटाए गए रिकॉर्ड को हटाने से डुप्लिकेट पंक्तियों में परिणाम हो सकता है, इसलिए ट्रिगर में पहले से हटाई गई पंक्ति पर हटाए गए_एटी फ़ील्ड को अपडेट नहीं करने की स्थिति है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. अंकगणित अतिप्रवाह त्रुटि अभिव्यक्ति को डेटा प्रकार डेटाटाइम में परिवर्तित करना

  2. अपने SQL सर्वर डेटाबेस का दस्तावेज़ कैसे करें

  3. शून्य मान को नवीनतम मान से बदलें

  4. SQL सर्वर डेटाबेस में सभी चेक बाधाओं को कैसे अक्षम करें - SQL सर्वर / TSQL ट्यूटोरियल भाग 87

  5. पेश है नई सुविधा - गतिरोध विश्लेषण