2009-12-02 19 views
21

मैं इस लेख पढ़ रहा था: Get null == null in SQLक्यों अशक्त बराबर नहीं शून्य पर है झूठी

और आम सहमति है कि जब दो (नल) एसक्यूएल स्तंभों के बीच समानता का परीक्षण करने की कोशिश कर रहा, सही दृष्टिकोण है:

where ((A=B) OR (A IS NULL AND B IS NULL)) 

जब ए और बी न्यूल हैं, (ए = बी) अभी भी गलत लौटाता है, क्योंकि न्यूल शून्य के बराबर नहीं है। यही कारण है कि अतिरिक्त जांच की आवश्यकता है।

असमानताओं का परीक्षण करते समय क्या होगा? उपरोक्त चर्चा से के बाद, यह मुझे लगता है कि परीक्षण असमानता को मैं की तरह कुछ करने के लिए की आवश्यकता होगी बनाया:

WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)) 

हालांकि, मैंने देखा है कि है कि जरूरी नहीं है (कम से कम इन्फोर्मिक्स 11.5 पर नहीं), और मैं यह कर सकते हैं बस करें:

where (A<>B) 

यदि ए और बी न्यूल हैं, तो यह गलत हो जाता है। यदि न्यूल शून्य के बराबर नहीं है, तो क्या यह सत्य वापस नहीं आना चाहिए?

संपादित
ये सब अच्छा जवाब हैं, लेकिन मुझे लगता है कि मेरे सवाल का एक छोटे से अस्पष्ट था। मुझे अलग तरीके से व्यक्त करने की अनुमति दें:

WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)) 
:

यह देखते हुए कि या तो ए या बी शून्य हो सकता है, यह काफी

where (A<>B) 

के साथ अपने असमानता की जाँच करने या मैं स्पष्ट रूप से इस तरह की जांच करने की आवश्यकता है है इस प्रश्न के उत्तर के लिए

इस thread पर रेफर करें।

+0

संक्षेप में में ऐसा कभी नहीं कर सकते हैं करने के लिए बदला जा सकता है, ' कुछ भी = नूल 'पूर्ण है (न तो सत्य और न ही झूठा)। और 'कुछ भी <> न्यूल' भी शून्य है। –

उत्तर

25

रिलेशनल शून्य वास्तव में उपज शून्य फिर

संपादित

यहाँ

, मनमाने ढंग से द्विआधारी ऑपरेटर के लिए <> खड़ा, NULL एसक्यूएल प्लेसहोल्डर है, और value किसी भी मूल्य है को शामिल भाव (NULLनहीं एक है मूल्य):

  • NULL <> value ->NULL
  • NULL <> NULL ->NULL

तर्क है: NULL का अर्थ है "कोई मूल्य नहीं" या "अज्ञात मूल्य", और इस प्रकार किसी भी वास्तविक मूल्य के साथ किसी भी तुलना कोई मतलब नहीं है।

X = 42 है, सही गलत, या अज्ञात, यह देखते हुए कि आप क्या मूल्य नहीं पता (यदि किसी भी) X रखती है? एसक्यूएल का कहना है कि यह अज्ञात है। X = Y सच, झूठा, या अज्ञात है, यह देखते हुए कि दोनों अज्ञात हैं? एसक्यूएल का कहना है कि परिणाम अज्ञात है। और यह किसी बाइनरी रिलेशनल ऑपरेशन के लिए ऐसा कहता है, जो केवल तार्किक है (भले ही मॉडल में एनयूएलएल पहले स्थान पर न हों)।

एसक्यूएल भी दो एकल पोस्टफ़िक्स ऑपरेटरों, IS NULL और IS NOT NULL प्रदान करता है, इन सही या गलत वापसी उनके संकार्य के अनुसार।

  • NULL IS NULL ->TRUE
  • NULL IS NOT NULL ->FALSE
+0

अरे, अपनी व्याख्या पढ़ने के बाद, मुझे "मेरे सिर में संकलन त्रुटि" मिलती है। मेरा मतलब है, फिर बाइनरी तुलना क्यों की अनुमति है? यदि मैं ए से चुनिंदा * लिखता हूं जहां Axxx <> null' मुझे खाली परिणाम सेट मिलता है। हालांकि, अगर मैं 'ए * से * चुनें * जहां नल' यह एक वाक्य रचनात्मक त्रुटि है। तो "मूल्य <> शून्य => शून्य" स्पष्टीकरण के साथ मेरे लिए कुछ काम नहीं कर रहा है ... क्या आप मेरी मदद कर सकते हैं कि इस बारे में 'सही' तरीका कैसे सोचें? – dingalapadum

+0

यह हो सकता है कि यह इसके बारे में सोचने के लिए और अधिक समझ में आएगा जैसे 'value <> null => false' और' value = null => false' भी? यह उस प्रकार की त्रुटि से बच जाएगा जिसके बारे में मैं बात कर रहा हूं। इसके अलावा इस तरह से कोई कारण हो सकता है कि 'मूल्य <> शून्य और 1 = 1' जैसे कुछ का अर्थ क्या है, जबकि' शून्य और 1 = 1' फिर से वाक्य रचनात्मक रूप से अजीब होगा ... जैसा कि मैंने कहा था, मैं बस कोशिश कर रहा हूं इस के चारों ओर मेरे सिर लपेटने के लिए। – dingalapadum

+0

'foo OP nULL' की अनुमति है क्योंकि SQL टूटा हुआ है। –

3

संक्षिप्त उत्तर है ... NULL अजीब हैं, वे वास्तव में आपकी अपेक्षा की तरह व्यवहार नहीं करते हैं।

यहां एक अच्छा पेपर है कि एनयूएलएल एसक्यूएल में कैसे काम करता है। मुझे लगता है कि यह विषय की आपकी समझ में सुधार करने में मदद करेगा। मुझे लगता है कि अभिव्यक्तियों में शून्य मूल्यों को संभालने के अनुभाग विशेष रूप से आपके लिए उपयोगी होंगे।

http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html

7

सभी null को शामिल तुलना अपरिभाषित हैं, और गलत पर मूल्यांकन करते हैं। यह विचार, null को null के बराबर मूल्यांकन करने से रोकता है, null को null के समतुल्य के रूप में मूल्यांकन के रूप में भी रोकता है।

+1

यह सुनिश्चित नहीं है कि इसे किसने कम किया है। 'Null 'के अलावा' null 'से जुड़ी कोई भी तुलना SQL मानक का पालन करने वाले डीबी पर झूठी वापसी होगी। – Donnie

+0

@ डोनी: धन्यवाद, मैं सोच रहा था कि मैं कहां गलत था। –

+3

मैंने किया। शून्य से जुड़ी कोई भी तुलना शून्य –

33

क्योंकि उस व्यवहार ternary logic जहां शून्य एक अज्ञात मूल्य माना जाता है की स्थापना इस प्रकार।

आप के रूप में अज्ञात शून्य के बारे में सोच रहे हैं, तो यह बहुत ज्यादा सहज हो जाता है:

unknown aunknown b के बराबर है? जानने का कोई तरीका नहीं है, इसलिए: unknown

+3

ग्रेट परिप्रेक्ष्य! इसे देखने का एक और तरीका यह है कि अगर "अज्ञात" "अज्ञात बी" के बराबर होता है, तो वे वास्तव में अज्ञात नहीं हो सकते हैं, क्योंकि आप उनके बारे में कुछ जानते हैं। क्वांटम मैकेनिक-वाई की तरह। – womp

+0

@womp: वास्तव में, आप जानते हैं कि आप नहीं जानते;) –

3

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

हालांकि एमएस एसक्यूएल सर्वर से निपटने के दौरान मैं कुछ किनारे के मामलों और चेतावनियों को सूचीबद्ध करता हूं जो सूचीबद्ध नहीं हैं।

  • एक बयान के भीतर नल जो मूल्यों को समूहीकृत कर रहे हैं उन्हें बराबर माना जाएगा और एक साथ समूहीकृत किया जाएगा।
  • उन आदेशों के भीतर शून्य मूल्यों को बराबर माना जाएगा।
  • अशक्त एक बयान है कि विशिष्ट उपयोग कर रहा है के भीतर चयनित मानों बराबर जब क्वेरी

यह विशिष्ट अशक्त के बारे में अभिव्यक्ति तर्क ओवरराइड करने के लिए SQL सर्वर की संभावनाओं की अलग पहलू का मूल्यांकन पर विचार किया जाएगा = अशक्त परीक्षण, SET ANSI_NULLS OFF का उपयोग करके, जो आपको शून्य मानों के बीच समानता प्रदान करेगा - यह एक अनुशंसित कदम नहीं है, लेकिन मौजूद है।

SET ANSI_NULLS OFF 

select result = 
    case 
     when null=null then 'eq' 
     else 'ne' 
    end 

SET ANSI_NULLS ON 

select result = 
    case 
     when null=null then 'eq' 
     else 'ne' 
    end 
0

"क्या अज्ञात बी के बराबर अज्ञात है? पता करने का कोई तरीका नहीं है, इसलिए: अज्ञात।"

सवाल यह था: तुलना उपज क्यों होती है?

तीन मूल्यवान तर्क को देखते हुए, यह वास्तव में UNKNOWN (FALSE नहीं) की तुलना के लिए समझदार होगा। लेकिन एसक्यूएल गलत उत्पन्न करता है, और अज्ञात नहीं है।

एसक्यूएल भाषा में विकृतियों के असंख्य में से एक।

इसके अलावा, निम्नलिखित को ध्यान में रखा जाना चाहिए:

तो "अज्ञात" त्रिगुट तर्क में एक तार्किक मान है, तो यह मामला होना चाहिए कि दो तार्किक मान है कि दोनों होने के लिए होने के बीच एक समानता तुलना (के लिए मूल्य) "अज्ञात", तो उस तुलना को सत्य उत्पन्न करना चाहिए।

यदि तार्किक मान स्वयं अज्ञात है, तो स्पष्ट रूप से उस पर "अज्ञात" मूल्य डालकर प्रतिनिधित्व नहीं किया जा सकता है, क्योंकि इसका अर्थ यह होगा कि तार्किक मान ज्ञात है ("अज्ञात" होना)। यही है, ए.ओ., कैसे संबंधपरक सिद्धांत साबित करता है कि 3-मूल्यवान तर्क लागू करने से 4-मूल्यवान तर्क की आवश्यकता बढ़ जाती है, कि एक 4 मूल्यवान तर्क 5 मूल्यवान तर्क आदि की आवश्यकता को जन्म देता है। विज्ञापन infinitum।

2

यहाँ एक त्वरित फिक्स है

IsNull (ए, 0) = IsNull (बी, 0)

0 कुछ है कि आपके डेटा

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