एक तालिका में पूर्ण मूल्य आत्म तुलना


13

मैं हमेशा निम्नलिखित की तरह कुछ रहस्यमय टी-एसक्यूएल व्यवहार के बारे में हैरान हूं

-- Create table t and insert values.  
use tempdb
CREATE TABLE dbo.t (a INT NULL);  
-- insert 3 values
INSERT INTO dbo.t values (NULL),(0),(1);  
GO  
set ansi_nulls off -- purposely turn off, so we can allow NULL comparison, such as null = null
go
-- expect 3 rows returned but only 2 returned (without null value row)
select * from dbo.t where a = a 

यह तालिका में सभी पंक्तियों को पुनः प्राप्त करने के बारे में नहीं है और ANSI_NULLS के उपयोग से बचने के बारे में भी नहीं है।

मैं बस कुछ अंतर्दृष्टि को टालना चाहता हूं कि टी-एसक्यूएल इस तरह का व्यवहार क्यों करता है।

जवाबों:


13

यह एक आश्चर्यजनक व्यवहार है लेकिन MSDN पृष्ठ से SET ANSI_NULLS, हम कम से कम यह जान सकते हैं कि अपेक्षित व्यवहार है। उपयोग न करने का एक और कारण ANSI_NULLS OFF:

SET ANSI_NULLSएक तुलना को प्रभावित करता है केवल अगर तुलना के ऑपरेंड में से एक एक चर है जो कि NULLया शाब्दिक है NULLयदि तुलना के दोनों किनारे स्तंभ या यौगिक अभिव्यक्ति हैं, तो सेटिंग तुलना को प्रभावित नहीं करती है।


8

हालांकि यह msdn प्रलेखन से स्पष्ट नहीं हो सकता है, मुझे विश्वास है कि आप निम्नलिखित सच पाएंगे

"SET ANSI_NULLS केवल एक तुलना को प्रभावित करता है यदि तुलना के ऑपरेंड में से एक या तो एक चर है जो NULL या शाब्दिक NULL है। यदि तुलना के दोनों पक्ष स्तंभ या यौगिक अभिव्यक्तियाँ हैं, तो सेटिंग तुलना को प्रभावित नहीं करती है।"

इसे देखें /programming/2866714/how-does-ans-nulls-work-in-tsql


धन्यवाद स्कॉट और ypercube, आपके दोनों उत्तर इस व्यवहार के बिंदुओं के लिए हैं, इसलिए मैं आपके दोनों उत्तरों को बढ़ाता हूं।
जिओ

Ypercube पहले था :)
स्कॉट हॉजगिन

4

2015 के बाद के पोस्ट में रॉबर्ट शेल्डन NULL व्यवहार और क्यों वे कभी-कभी (लेकिन हमेशा नहीं) असफल होने पर चर्चा करते हैं

https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

वह 13 पूर्ण विफलताओं का वर्णन करता है जो एक प्रोग्रामर आसानी से यात्रा कर सकता है।

असफलता # 1: यह जानने का नहीं कि NULL का मतलब क्या है

स्पष्टीकरण: NULL एक गैर-मूल्य है, एक गैर-मूल्य है। यह शून्य नहीं है। यह एक खाली स्ट्रिंग नहीं है। एक मान NULL के बराबर नहीं हो सकता। कोई दो NULL मान समान नहीं हैं

यह मूल समस्या है, लेकिन अन्य विफलताओं के बारे में पढ़ना सुनिश्चित करें।

हां, पहले के संस्करण (प्री-SQL सर्वर 7 मेरा मानना ​​है) अलग तरह से व्यवहार करते हैं, और अधिक जैसे आप चाहते हैं।

हालाँकि, यदि आप स्टैक ओवरफ़्लो और स्टैक एक्सचेंज पर समस्या की खोज करते हैं, तो आपको मुद्दों पर चर्चा करने वाले कई लंबे धागे मिलेंगे।


3
मैंने एक बार रॉबर्ट शेल्डन से लिंक की गई पोस्ट को पढ़ा, लेकिन इसमें (IMHO) ऐसा कोई सिद्धांत या सबूत नहीं है जो मेरे उदाहरण के व्यवहार की व्याख्या करता हो।
जिओ

1
"कोई दो NULL मान समान नहीं हैं।" ठीक है, लेकिन यहां तक ​​कि उन लोगों को भी पता है जो एएनआई नल को बंद करने के लिए विपरीत की उम्मीद करेंगे। खासकर क्योंकि WHERE NULL = NULLपैदावार सही होने पर पैदावार होती है।
ypercube y

1

चर्चा में जोड़ने के लिए, SQL92 मानक की NULL की परिभाषा अस्पष्ट रूप से व्याख्या की जा सकती है। यहां sqlite.org के विभिन्न DBMSes शिष्टाचार से NULL हैंडलिंग और व्याख्या का अच्छा सारांश है

अस्वीकरण : मुझे याद है कि sqlite.org पृष्ठ के पुराने संस्करण (जैसे 6-8 साल पहले) से SQL92 के "अस्पष्टता" के बारे में पढ़ना उपरोक्त से जुड़ा हुआ है, लेकिन उस पृष्ठ को तब से अपडेट किया गया है।

ऊपर RLF के उत्तर की एक अच्छी बोली है, लेकिन अगर मैं रॉबर्ट शेल्डन के साथ असहमत हूं, तो यह केवल इसलिए है क्योंकि मैं "कुछ ऐसा है जो अस्तित्व में नहीं है" (यानी एक NULL ) को दार्शनिक और अंग्रेजी-भाषा-शब्दार्थ "कुछ ऐसा है जो मौजूद नहीं है के बराबर" मानता है। "। अगर मुझे शेल्डन के तर्क को समझना है, तो कोई NULL की परिभाषा भी घोषित कर सकता है। (यदि यह मौजूद नहीं है, तो हम इसे कैसे परिभाषित कर सकते हैं? डरावना, हुह?)

मुझे रसेल के विरोधाभास काढ़ा ( और एक सिरदर्द) की विविधता दिखाई देती है । : - \

लेकिन फिर, यह अंग्रेजी भाषा के शब्दार्थ ( एसक्यूएल) पर चर्चा नहीं है और दर्शन बहस यहाँ पर है । :-)


PS मैं यहाँ इस एसई समुदाय के लिए नया हूँ; यदि इससे पहले विज्ञापन nauseum पर चर्चा की गई है , तो मैं माफी माँगता हूँ।
pr1268

1
मानक में अस्पष्टता कहाँ है?
ypercube y

@ ypercube y: मेरा मानना ​​है कि एक बूलियन में 3VL को "फिट" करने के प्रयास में अस्पष्टता निहित है । NULL तुलनाओं के साथ तालिका में जुड़ने की कई अलग-अलग तरीकों से व्याख्या की जा सकती है।
2:12 पर pr1268

मैं असंगति के बारे में सहमत हूं लेकिन अस्पष्टता के बारे में नहीं।
ypercube y

1
@ ypercube y: पर्याप्त रूप से ... मैं केवल उद्धृत कर रहा था कि sqlite.org पृष्ठ का एक पुराना संस्करण जो मैंने ऊपर कहा है ("SQL92 NULL हैंडलिंग और व्याख्या के संबंध में अस्पष्ट है" या बहुत समान है)। लेकिन मेरा मतलब बहस करने से नहीं है। शायद sqlite.org पेज ही भ्रामक और / या ऑल-आउट गलत था। कौन सा संभावित कारण बताता है कि इसे क्यों अपडेट किया गया था।
pr1268
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.