यदि आप कभी खुद को ऐसी स्थिति में पाते हैं जहां आपको CHECK
. को फिर से सक्षम करने की आवश्यकता होती है बाधा जिसे पहले अक्षम कर दिया गया है, आपको निश्चित रूप से सुनिश्चित करना चाहिए कि आप जानते हैं कि आप क्या कर रहे हैं।
विशेष रूप से, आपको WITH NOCHECK
. के बीच के अंतर को समझना चाहिए और WITH CHECK
तर्क।
इन तर्कों का उपयोग उस समय किया जा सकता है जब आप बाधा को सक्षम करते हैं। वे निर्दिष्ट करते हैं कि मौजूदा डेटा आपके पुन:सक्षम (या नए जोड़े गए) CHECK
के विरुद्ध मान्य है या नहीं बाधा मूल रूप से आपके पास बाधा के विरुद्ध किसी भी उल्लंघन के लिए सभी मौजूदा डेटा की जांच करने का विकल्प है। यदि आप कुछ निर्दिष्ट नहीं करते हैं, तो मौजूदा डेटा नहीं जाँच की जाए। इसलिए यह समझना महत्वपूर्ण है कि यह कैसे काम करता है।
वैसे, ये तर्क विदेशी कुंजी बाधाओं पर भी लागू होते हैं।
जैसा कि आप उम्मीद कर सकते हैं, WITH CHECK
निर्दिष्ट करता है कि मौजूदा डेटा मान्य है और WITH NOCHECK
निर्दिष्ट करता है कि यह नहीं है। डिफ़ॉल्ट WITH NOCHECK
. है ।
यदि आप WITH NOCHECK
. का उपयोग करते हैं , बाधा को अविश्वसनीय के रूप में चिह्नित किया जाएगा। वास्तव में, जब आप बाधा को अक्षम करते हैं तो इसे अविश्वसनीय के रूप में फ़्लैग किया जाता है। लेकिन जब आप इसे फिर से सक्षम करते हैं, तो यह तब तक अविश्वसनीय रहेगा जब तक आप WITH CHECK
का उपयोग नहीं करते हैं। . दूसरे शब्दों में, यदि आप इसकी "विश्वसनीयता" को फिर से बताना चाहते हैं, तो आपको इसे स्पष्ट रूप से निर्दिष्ट करना होगा।
दूसरे शब्दों में:
- जब आप
WITH NOCHECK
का उपयोग करते हैं , बाधा अविश्वसनीय रहेगी। - जब आप
WITH CHECK
का उपयोग करते हैं यह विश्वसनीय हो जाएगा, लेकिन केवल तभी जब सभी मौजूदा डेटा बाधा के अनुरूप हों। यदि कोई मौजूदा डेटा बाधा का उल्लंघन करता है, तो बाधा सक्षम नहीं होगी और आपको एक त्रुटि संदेश प्राप्त होगा।
बेशक, जब मैं "सभी मौजूदा डेटा" कहता हूं, तो मैं केवल उस डेटा की बात कर रहा हूं, जिस पर प्रतिबंध लागू होता है।
ऐसे परिदृश्य हो सकते हैं जहां आपने जानबूझकर एक बाधा को अक्षम कर दिया क्योंकि आपको डेटा दर्ज करना था जो बाधा का उल्लंघन करता है। ऐसे मामलों में, यदि अमान्य डेटा डेटाबेस में रहना चाहिए, तो आपको WITH NOCHECK
का उपयोग करना होगा यदि आप बाधा को फिर से सक्षम करना चाहते हैं। यह आपको बिना किसी मौजूदा डेटा के बाधा को सक्षम करने की अनुमति देगा।
नीचे ऐसे उदाहरण दिए गए हैं जो इसे प्रदर्शित करते हैं।
उदाहरण 1 - चेक बाधाओं की समीक्षा करें
सबसे पहले, आइए sys.check_constraints
. का उपयोग करें सभी पर एक नज़र डालने के लिए CHECK
वर्तमान डेटाबेस में बाधाएं।
SELECT name, is_disabled, is_not_trusted, definition FROM sys.check_constraints;
परिणाम:
+-----------------+---------------+------------------+----------------------------------------+ | name | is_disabled | is_not_trusted | definition | |-----------------+---------------+------------------+----------------------------------------| | chkPrice | 0 | 0 | ([Price]>(0)) | | chkValidEndDate | 0 | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | 0 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | 0 | ([JobTitle]<>'Digital Nomad') | +-----------------+---------------+------------------+----------------------------------------+
हम देख सकते हैं कि वे सभी सक्षम और विश्वसनीय हैं (क्योंकि उन सभी के पास is_disabled में शून्य है और is_not_trusted कॉलम)।
इस लेख के लिए, मैं chkJobTitle को अक्षम और पुन:सक्षम कर दूंगा बाधा।
उदाहरण 2 - प्रतिबंध को अक्षम करें
यहाँ, मैं chkJobTitle . को अक्षम करता हूँ बाधा:
ALTER TABLE Occupation NOCHECK CONSTRAINT chkJobTitle;
हो गया।
आइए अब सभी बाधाओं की फिर से समीक्षा करें:
SELECT name, is_disabled, is_not_trusted, definition FROM sys.check_constraints;
परिणाम:
+-----------------+---------------+------------------+----------------------------------------+ | name | is_disabled | is_not_trusted | definition | |-----------------+---------------+------------------+----------------------------------------| | chkPrice | 0 | 0 | ([Price]>(0)) | | chkValidEndDate | 0 | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | 0 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 1 | 1 | ([JobTitle]<>'Digital Nomad') | +-----------------+---------------+------------------+----------------------------------------+
हम देख सकते हैं कि इसे अक्षम कर दिया गया है (क्योंकि इसका is_disabled . है कॉलम 1 . पर सेट है )।
आप देख सकते हैं कि
is_not_trusted
कॉलम
1
. पर भी सेट है . यह इंगित करता है कि CHECK
सिस्टम द्वारा सभी पंक्तियों के लिए बाधा सत्यापित नहीं की गई है।
जैसा कि उल्लेख किया गया है, एक CHECK
बाधा पर तभी भरोसा किया जा सकता है जब सभी डेटा ने बाधा की शर्तों को सफलतापूर्वक पार कर लिया हो। जब हम एक बाधा को अक्षम करते हैं, तो यह अमान्य डेटा के डेटाबेस में प्रवेश करने की क्षमता को खोलता है। इसलिए हम 100% निश्चित नहीं हो सकते हैं कि सभी डेटा मान्य है, इसलिए बाधा को विश्वसनीय नहीं के रूप में चिह्नित किया जा रहा है।
यह सुनिश्चित करने का तरीका है कि बाधा पर फिर से भरोसा किया जाए WITH CHECK
का उपयोग करके इसे फिर से सक्षम करना है बहस। यह फिर से सक्षम होने से पहले सभी डेटा की जांच करने के लिए बाधा उत्पन्न करेगा। अगर कोई डेटा अमान्य है, तो उसे फिर से चालू नहीं किया जा सकेगा. आपको या तो डेटा को अपडेट करना होगा ताकि यह मान्य हो, या WITH NOCHECK
का उपयोग करके बाधा को फिर से सक्षम करना होगा। इसके बजाय तर्क (जो बाधा को अविश्वसनीय बना देगा)।
उदाहरण 3 - डिफ़ॉल्ट सेटिंग्स (NOCHECK के साथ) का उपयोग करके बाधा को सक्षम करें
आइए बाधा को फिर से सक्षम करें और क्वेरी को फिर से चलाएँ।
बाधा को सक्षम करने के लिए, मैं आलसी हो जाऊंगा और डिफ़ॉल्ट सेटिंग्स का उपयोग करूंगा:
ALTER TABLE Occupation CHECK CONSTRAINT chkJobTitle;
अब बदलाव की पुष्टि करें:
SELECT name, is_disabled, is_not_trusted, definition FROM sys.check_constraints;
परिणाम:
+-----------------+---------------+------------------+----------------------------------------+ | name | is_disabled | is_not_trusted | definition | |-----------------+---------------+------------------+----------------------------------------| | chkPrice | 0 | 0 | ([Price]>(0)) | | chkValidEndDate | 0 | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | 0 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | 1 | ([JobTitle]<>'Digital Nomad') | +-----------------+---------------+------------------+----------------------------------------+
क्या आपने देखा कि अभी क्या हुआ? हालांकि मैंने बाधा को फिर से सक्षम किया है, फिर भी यह विश्वसनीय नहीं है।
ऐसा इसलिए है क्योंकि जब मैंने बाधा को सक्षम किया तो मैं आलसी (या शायद केवल भुलक्कड़) था। जब मैंने बाधा को सक्षम किया, तो मैं WITH CHECK
निर्दिष्ट करना भूल गया . डिफ़ॉल्ट WITH NOCHECK
. है जिसका अर्थ है कि बाधा को पुन:सक्षम करते समय मौजूदा डेटा की जाँच नहीं की जाती है।
यही कारण है कि आपको निश्चित रूप से पता होना चाहिए कि CHECK
. को सक्षम करते समय आप क्या कर रहे हैं? (और FOREIGN KEY
) प्रतिबंध। आलसी होने और संभावित रूप से महत्वपूर्ण सेटिंग को स्पष्ट रूप से निर्दिष्ट न करके, हम मौजूदा डेटा के साथ किसी भी समस्या पर आंखें मूंदने के लिए SQL सर्वर को अनुमति देते हैं।
हालाँकि, यदि आपको बाधा को अक्षम करने के लिए आवश्यक संपूर्ण कारण डेटा सम्मिलित करना है जो बाधा का उल्लंघन करता है, तो डिफ़ॉल्ट WITH NOCHECK
शायद वही है जो आप चाहते हैं।
वैसे, नई बाधाओं के लिए, डिफ़ॉल्ट WITH CHECK
. है ।
लेकिन मेरे मामले में, मैंने कोई भी . नहीं डाला या अपडेट नहीं किया डेटा बाधा को अक्षम करने के बाद, इसलिए यदि यह पहले भरोसेमंद था, तो इसे अब भी भरोसेमंद होना चाहिए।
तो मैं अपनी बाधा पर फिर से कैसे भरोसा कर सकता हूँ?
उदाहरण 4 - चेक के साथ उपयोग कर प्रतिबंध को सक्षम करें
अगर मैं चाहता हूं कि मेरी बाधा पर फिर से भरोसा किया जाए, तो मुझे स्पष्ट रूप से WITH CHECK
निर्दिष्ट करना होगा इसे पुन:सक्षम करते समय।
आइए फिर से बाधा को अक्षम करें:
ALTER TABLE Occupation NOCHECK CONSTRAINT chkJobTitle;
इसलिए अब मैं वापस वहीं आ गया हूं जहां मैं इसे फिर से सक्षम करने से पहले था।
जब मैंने पुनः सक्षम किया तो मुझे क्या करना चाहिए था:
ALTER TABLE Occupation WITH CHECK CHECK CONSTRAINT chkJobTitle;
अब बाधा पर एक और नज़र डालें:
SELECT name, is_disabled, is_not_trusted, definition FROM sys.check_constraints;
परिणाम:
+-----------------+---------------+------------------+----------------------------------------+ | name | is_disabled | is_not_trusted | definition | |-----------------+---------------+------------------+----------------------------------------| | chkPrice | 0 | 0 | ([Price]>(0)) | | chkValidEndDate | 0 | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | 0 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | 0 | ([JobTitle]<>'Digital Nomad') | +-----------------+---------------+------------------+----------------------------------------+
ओह! मेरी मजबूरी एक बार फिर भरोसेमंद है।
उदाहरण 5 - अमान्य डेटा के साथ CHECK बाधा को सक्षम करें
बेशक, मेरी बाधा पर केवल फिर से भरोसा किया जाता है क्योंकि मैंने अक्षम होने पर अमान्य डेटा सम्मिलित नहीं किया था। अगर मैंने ऐसा किया होता, तो मैं WITH CHECK
. का उपयोग करके इसे सक्षम नहीं कर पाता , जैसा कि नीचे दिखाया गया है।
अगर मैं इसे फिर से अक्षम कर दूं:
ALTER TABLE Occupation NOCHECK CONSTRAINT chkJobTitle;
अब अमान्य डेटा डालें (और परिणाम लौटाएं):
INSERT INTO Occupation VALUES ( 7, 'Digital Nomad' ); SELECT OccupationId, JobTitle FROM Occupation;
परिणाम:
+----------------+-----------------+ | OccupationId | JobTitle | |----------------+-----------------| | 1 | Engineer | | 2 | Accountant | | 3 | Cleaner | | 4 | Attorney | | 5 | Sales Executive | | 6 | Uber Driver | | 7 | Digital Nomad | +----------------+-----------------+
इसलिए हमने सफलतापूर्वक अमान्य डेटा (अंतिम पंक्ति) डाला।
यह अमान्य है क्योंकि बाधा परिभाषा इस प्रकार है:([JobTitle]<>'Digital Nomad')
इसका मतलब है कि
JobTitle
कॉलम में Digital Nomad
टेक्स्ट नहीं होना चाहिए ।
आइए अब CHECK
. को पुन:सक्षम करने का प्रयास करें WITH CHECK
का उपयोग करने में बाधा और देखें कि क्या होता है।
ALTER TABLE Occupation WITH CHECK CHECK CONSTRAINT chkJobTitle;
परिणाम:
Msg 547, Level 16, State 0, Line 1 The ALTER TABLE statement conflicted with the CHECK constraint "chkJobTitle". The conflict occurred in database "Test", table "dbo.Occupation", column 'JobTitle'.
इसलिए हम WITH CHECK
. का उपयोग करके बाधा को फिर से सक्षम नहीं कर सकते हैं जबकि हमारे पास तालिका में डेटा है जो CHECK
. का उल्लंघन करता है बाधा या तो हमें डेटा अपडेट करने की जरूरत है या हमें WITH NOCHECK
. का उपयोग करने की आवश्यकता है (या बस इसे पूरी तरह से छोड़ दें)।
आइए WITH NOCHECK
. का उपयोग करके इसे फिर से देखें ।
ALTER TABLE Occupation WITH NOCHECK CHECK CONSTRAINT chkJobTitle;
परिणाम:
Commands completed successfully. Total execution time: 00:00:00.015
इसलिए यदि हम मौजूदा डेटा की जांच नहीं करते हैं तो हम बाधा को सफलतापूर्वक सक्षम कर सकते हैं।
बेशक, इस मामले में CHECK
बाधा अभी भी विश्वसनीय नहीं है। अगर हम चाहते हैं कि बाधा पर भरोसा किया जाए, तो हमें डेटा को अपडेट करना होगा ताकि यह बाधा का उल्लंघन न करे।
उदाहरण:
UPDATE Occupation SET JobTitle = 'Unemployed' WHERE OccupationId = 7; SELECT OccupationId, JobTitle FROM Occupation;
परिणाम:
+----------------+-----------------+ | OccupationId | JobTitle | |----------------+-----------------| | 1 | Engineer | | 2 | Accountant | | 3 | Cleaner | | 4 | Attorney | | 5 | Sales Executive | | 6 | Uber Driver | | 7 | Unemployed | +----------------+-----------------+
अब हम CHECK
. को बदल सकते हैं फिर से भरोसेमंद बनने के लिए बाधा।
आइए तीनों को एक साथ करें:
ALTER TABLE Occupation NOCHECK CONSTRAINT chkJobTitle; ALTER TABLE Occupation WITH CHECK CHECK CONSTRAINT chkJobTitle; SELECT name, is_disabled, is_not_trusted, definition FROM sys.check_constraints;
परिणाम:
+-----------------+---------------+------------------+----------------------------------------+ | name | is_disabled | is_not_trusted | definition | |-----------------+---------------+------------------+----------------------------------------| | chkPrice | 0 | 0 | ([Price]>(0)) | | chkValidEndDate | 0 | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | 0 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | 0 | ([JobTitle]<>'Digital Nomad') | +-----------------+---------------+------------------+----------------------------------------+
तो अब हमारी बाधा एक बार फिर सक्षम और भरोसेमंद है, और हमारा डेटाबेस डिजिटल खानाबदोशों से मुक्त है!