Oracle 9i एक खाली स्ट्रिंग को NULL क्यों मानता है?


216

मुझे पता है कि यह '' के रूप में विचार करता हैNULL , लेकिन यह मुझे बताने के लिए बहुत कुछ नहीं करता कि ऐसा क्यों है। जैसा कि मैं एसक्यूएल विनिर्देशों को समझता हूं, '' एक जैसा नहीं है NULL- एक वैध डेटा है, और दूसरा उसी जानकारी के अभाव का संकेत दे रहा है।

अटकलें बेझिझक लगाइए, लेकिन कृपया इंगित करें कि क्या ऐसा है। यदि ओरेकल से कोई है जो इस पर टिप्पणी कर सकता है, तो यह शानदार होगा!


9
बेझिझक कल्पना करें? किसी तरह मुझे नहीं लगता है कि आपको उत्तर का सबसे बड़ा सेट प्रदान करेगा ..
SCdF

1
मुझे नहीं लगता, लेकिन मुझे यकीन नहीं था कि इस विषय पर कोई निश्चितता होगी, इसलिए मुझे लगा कि मैं दरवाजे खोल दूंगा। लगता है अब तक ठीक काम किया है।
क्रिस आर


जवाबों:


216

मेरा मानना ​​है कि उत्तर यह है कि ओरेकल बहुत, बहुत पुराना है।

SQL मानक होने से पहले पुराने दिनों में, ओरेकल ने डिज़ाइन निर्णय लिया था कि VARCHAR/ VARCHAR2कॉलम में खाली तार थे NULLऔर NULL का केवल एक ही अर्थ था (संबंधपरक सिद्धांत हैं जो उन डेटा के बीच अंतर करेंगे जिन्हें कभी भी संकेत नहीं दिया गया है, में डेटा जहां उत्तर मौजूद है, लेकिन उपयोगकर्ता द्वारा ज्ञात नहीं है, डेटा जहां कोई जवाब नहीं है, आदि सभी जिनमें से कुछ का गठन होता है NULL)।

उस समय जब तक SQL मानक चारों ओर आ गया और सहमत हो गया कि NULLऔर खाली स्ट्रिंग अलग-अलग इकाइयाँ थीं, पहले से ही Oracle उपयोगकर्ता थे जिनके पास कोड था जो दोनों को समान मानते थे। इसलिए ओरेकल मूल रूप से मौजूदा कोड को तोड़ने, एसक्यूएल मानक का उल्लंघन करने, या कुछ प्रकार के आरंभीकरण पैरामीटर को शुरू करने के विकल्पों के साथ छोड़ दिया गया था, जो संभावित बड़ी संख्या में प्रश्नों की कार्यक्षमता को बदल देगा। SQL मानक (IMHO) का उल्लंघन इन तीन विकल्पों में से सबसे कम विघटनकारी था।

ओरेकल ने संभावना को खुला छोड़ दिया है कि VARCHARSQL मानक का पालन करने के लिए डेटा प्रकार भविष्य के रिलीज में बदल जाएगा (यही कारण है कि हर कोई VARCHAR2ओरेकल में उपयोग करता है क्योंकि डेटा प्रकार का व्यवहार उसी तरह आगे रहने की गारंटी है)।


60

ओरेकल के टॉम क्यूटी वीपी:

शून्य लंबाई वाली वैरायटी को NULL के रूप में माना जाता है।

'' को NULL नहीं माना जाता है।

'' जब एक चर (1) को सौंपा जाता है '' (चार प्रकार के खाली गद्देदार तार होते हैं)।

'' जब एक varchar2 को सौंपा गया (1) बन जाता है '' जो एक शून्य लंबाई स्ट्रिंग है और एक शून्य लंबाई स्ट्रिंग Oracle में NULL है (यह कोई लंबा नहीं है '')


17
वाह, टॉम बहुत सुंदर। यह देखते हुए कि प्रश्न SQL92 से एक अहंकारी विचलन से संबंधित हैं, आपको लगता है कि वह इसके बारे में कम छिद्रपूर्ण होगा ... हालांकि वह जवाब देने से थक सकता है।
क्रिस आर

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

9
लेकिन यह अधिक सटीक होगा यदि दूसरी पंक्ति को ''
ypercube y

2
@ypercube टॉम द्वारा वास्तव में उपयोग किए जाने वाले शब्द को बदलकर उद्धरण अधिक सटीक नहीं मिलता है। अगर आपको लगता है कि टॉम ने इसे भ्रामक रूप से लिखा है, एमएमएम। शायद। मुझे लगता है कि वह हाजिर है । सबसे भ्रामक स्थितियों उठता है जब ''की जा रही है implicitely एक VARCHAR2, करने के लिए परिवर्तित जैसे cast('' as char(1)) is nullजो है ... आश्चर्यजनक रूप से सही
sehe

1
@ मेरे लिए भ्रामक बिट दोहरे से 1 का चयन करें जहां ('' अशक्त) है
मैट विदाई

20

मुझे संदेह है कि यह बहुत अधिक समझ में आता है अगर आप ओरेकल के बारे में सोचते हैं जो पहले डेवलपर्स ने शायद किया था - डेटा एंट्री सिस्टम के लिए एक शानदार बैकेंड के रूप में। डेटाबेस में प्रत्येक फ़ील्ड एक ऐसे फ़ील्ड से मेल खाती है जिसे डेटा एंट्री ऑपरेटर अपनी स्क्रीन पर देखता है। यदि ऑपरेटर किसी क्षेत्र में कुछ भी टाइप नहीं करता है, चाहे वह "जन्मतिथि" या "पता" हो, तो उस फ़ील्ड का डेटा "अज्ञात" है। किसी ऑपरेटर के लिए यह इंगित करने का कोई तरीका नहीं है कि किसी का पता वास्तव में एक रिक्त स्ट्रिंग है, और यह वास्तव में बहुत अधिक समझ में नहीं आता है।


5
यह केवल तभी समझ में आता है जब आप मान लेते हैं कि डेटा एंट्री सिस्टम में हर क्षेत्र अनिवार्य है। गैर-अनिवार्य फ़ील्ड (जैसे "डॉग्स नेम") का एक गैर-उत्तर मान्य है, इसलिए रिक्त स्ट्रिंग का अभी भी NULL के लिए एक अलग उद्देश्य है। यहां तक ​​कि उस जगह पर धारणा के साथ, मुझे संदेह है कि शुरुआती डेवलपर्स ने ओरेकल के बारे में सोचा था कि "डेटा एंट्री सिस्टम के लिए गौरवशाली बैकेंड" है, इसलिए मुझे यकीन नहीं है कि यह जवाब बिल्कुल भी समझ में नहीं आता है।
जारेड

19

ओरेकल प्रलेखन डेवलपर्स को इस समस्या से सचेत करता है, कम से कम संस्करण 7 तक।

Oracle ने "असंभव मान" तकनीक द्वारा NULLS का प्रतिनिधित्व करने के लिए चुना। उदाहरण के लिए, एक संख्यात्मक स्थान में एक NULL को "शून्य शून्य", एक असंभव मूल्य के रूप में संग्रहीत किया जाएगा। किसी भी माइनस जीरो जो कि संगणनाओं से उत्पन्न होते हैं, उन्हें स्टोर किए जाने से पहले सकारात्मक शून्य में बदल दिया जाएगा।

Oracle ने त्रुटिपूर्ण रूप से चुना, लंबाई शून्य (रिक्त स्ट्रिंग) के VARCHAR स्ट्रिंग को एक असंभव मान माना, और NULL का प्रतिनिधित्व करने के लिए एक उपयुक्त विकल्प। यह पता चला है कि खाली स्ट्रिंग एक असंभव मूल्य से दूर है। यह स्ट्रिंग संघनन के संचालन के तहत भी पहचान है!

ओरेकल प्रलेखन डेटाबेस डिजाइनरों और डेवलपर्स को चेतावनी देता है कि ओरेकल के कुछ भविष्य के संस्करण इस एसोसिएशन को खाली स्ट्रिंग और NULL के बीच तोड़ सकते हैं, और उस एसोसिएशन पर निर्भर किसी भी कोड को तोड़ सकते हैं।

असंभव मूल्यों के अलावा NULLS को ध्वजांकित करने की तकनीकें हैं, लेकिन Oracle ने उनका उपयोग नहीं किया।

(मैं एक पंक्ति और एक स्तंभ के प्रतिच्छेदन का मतलब ऊपर "स्थान" शब्द का उपयोग कर रहा हूं।)


ओरेकल प्रलेखन डेटाबेस डिजाइनरों और डेवलपर्स को चेतावनी देता है कि ओरेकल के कुछ भविष्य के संस्करण इस एसोसिएशन को खाली स्ट्रिंग और NULL के बीच तोड़ सकते हैं, और उस एसोसिएशन पर निर्भर किसी भी कोड को तोड़ सकते हैं - क्या आप इस कथन के लिए संदर्भ प्रदान कर सकते हैं?
पियोत्र डोब्रोगोस्ट


2

खाली स्ट्रिंग केवल NULL की तरह ही है क्योंकि इसकी "कम बुराई" स्थिति की तुलना में जब दो (खाली स्ट्रिंग और नल) समान नहीं होती है।

उन भाषाओं में जहां NULL और खाली स्ट्रिंग समान नहीं हैं, किसी को हमेशा दोनों स्थितियों की जांच करनी होती है।


बस not nullअपने स्तंभ पर बाधा निर्धारित करें और केवल खाली स्ट्रिंग पर जांचें।
ईगोर स्क्रीप्टुनॉफ

6
दोनों स्थितियों की जाँच करना तुच्छ है: WHERE Field <> ''केवल तभी सही है जब रिक्त स्थान के लिए ANSI व्यवहार वाले डेटाबेस पर फ़ील्ड NULL और रिक्त नहीं है।

1

आधिकारिक 11 जी डॉक्स के अनुसार

ओरेकल डेटाबेस वर्तमान में शून्य के रूप में शून्य के साथ एक चरित्र मान मानता है। हालांकि, यह भविष्य के रिलीज में सच नहीं हो सकता है, और ओरेकल की सिफारिश है कि आप खाली तारों को नल के समान नहीं मानते हैं।

संभावित कारण

  1. val IS NOT NULL से अधिक पठनीय है val != ''
  2. दोनों स्थितियों की जाँच करने की आवश्यकता नहीं है val != '' and val IS NOT NULL

5
पूरी तरह से एएनएसआई-अनुरूप डेटाबेस में, आपको दोनों स्थितियों की जांच करने की आवश्यकता नहीं है। val <> ''पहले से ही शामिल नहीं है NULL। शायद आपका मतलब था val = '' OR val IS NULL। लेकिन खाली तार जो NULL की तुलना में उपयोगी नहीं हैं !
एरिक

मैं तुलनात्मक भाग से सहमत हूं।
सॉर्टर

0

पुस्तक से उदाहरण

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;

-1

क्योंकि NULL के रूप में इसका इलाज नहीं करना विशेष रूप से मददगार नहीं है।

यदि आप ओरेकल पर इस क्षेत्र में गलती करते हैं, तो आप आमतौर पर तुरंत ध्यान देते हैं। SQL सर्वर में, हालांकि, यह काम करने के लिए दिखाई देगा, और समस्या केवल तब दिखाई देती है जब कोई व्यक्ति NULL (शायद एक .net क्लाइंट लाइब्रेरी से, जहां null "" से अलग है, के बजाय एक खाली स्ट्रिंग में प्रवेश करता है, लेकिन आप आमतौर पर उनसे एक ही व्यवहार करते हैं। )।

मैं नहीं कह रहा हूँ कि ओरेकल सही है, लेकिन मुझे ऐसा लगता है कि दोनों तरीके लगभग समान रूप से खराब हैं।


2
बहुत, डिबग करने के लिए और अधिक आसान। इसके अलावा, यदि आप स्क्रीन पर एक खाली सेल या इनपुट देखते हैं, तो आपको पता है कि DB में डेटा शून्य है। अन्य DBs में, जहां '' <> NULL, आप "देख नहीं सकते" यदि डेटा अशक्त या '' है, तो यह बहुत डरपोक बग की ओर जाता है। '' = अशक्त यह सबसे अच्छा विकल्प है, भले ही यह मानक न हो।
लुसियो एम। टेटो

2
"अन्य DBs में जहां '' <> NULL, आप डेटा को शून्य या ''" नहीं देख सकते हैं "" = "> आमतौर पर, DB टूल्स रिक्त स्ट्रिंग्स से भिन्न रूप से NULL को प्रदर्शित करते हैं। वास्तव में, यहां तक ​​कि ओरेकल SQL डेवलपर NULLs को "(अशक्त)" के रूप में दिखाता है। मुझे लगता है कि यह NULL को व्हॉट्सएप से अलग करना है लेकिन यह NULL और खाली स्ट्रिंग्स के बीच अंतर से संबंधित नहीं है।
डिडिएर एल

-6

वास्तव में, मुझे ओरेकल से निपटने में कुछ भी नहीं है, जिसमें अमान्य डेटाटाइम मान (मुद्रित नहीं किया जा सकता है, परिवर्तित या कुछ भी नहीं हो सकता है), बस DUMP () फ़ंक्शन के साथ देखा गया है, जिसे डेटाबेस में डालने की अनुमति है, जाहिर है कुछ छोटी गाड़ी के माध्यम से बाइनरी कॉलम के रूप में क्लाइंट का संस्करण! डेटाबेस अखंडता की रक्षा के लिए इतना!

NULLs लिंक की Oracle हैंडलिंग:

http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/

http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html


1
अमान्य डेटाटाइम मान? उसके अर्थ के बारे में सुनिश्चित रूप से नहीं पता है। क्या आपने इसे यहां एक प्रश्न के रूप में पोस्ट किया है?

1
समस्या पूर्व दिनांकित स्टैक्वेरफ़्लो - मुझे ओरेकल फ़ोरम से कोई उपयोगी जानकारी नहीं मिली और मैंने वर्कअराउंड बनाया - मैं अपने नोट्स नीचे ट्रैक करूँगा और यहाँ पोस्ट करूँगा।
केड रूक्स

यहाँ एक प्रश्न के रूप में विवरण पोस्ट किया।
राडेक्स

-6

सबसे पहले, अशक्त और अशक्त स्ट्रिंग को हमेशा ओरेकल द्वारा समान नहीं माना जाता था। एक अशक्त स्ट्रिंग है, परिभाषा के अनुसार, एक स्ट्रिंग जिसमें कोई वर्ण नहीं है। यह एक नल के समान बिल्कुल नहीं है। NULL, परिभाषा के अनुसार, डेटा की अनुपस्थिति है।

पाँच या छह साल या उससे पहले, अशक्त स्ट्रिंग को ओरेकल द्वारा अशक्त से अलग तरीके से व्यवहार किया गया था। हालांकि, नल की तरह, नल स्ट्रिंग सब कुछ के बराबर था और हर चीज से अलग था (जो मुझे लगता है कि नल के लिए ठीक है, लेकिन पूरी तरह से गलत स्ट्रिंग के लिए गलत है), कम से कम लंबाई (नल स्ट्रिंग) 0 वापस आ जाएगी, क्योंकि यह नल स्ट्रिंग के बाद से होना चाहिए शून्य लंबाई की एक स्ट्रिंग।

वर्तमान में ओरेकल में, लंबाई (अशक्त) शून्य है जो मुझे लगता है कि ठीक है, लेकिन लंबाई (अशक्त स्ट्रिंग) भी अशक्त है जो पूरी तरह से गलत है।

मुझे समझ में नहीं आता कि उन्होंने इन 2 विशिष्ट "मूल्यों" का इलाज शुरू करने का फैसला क्यों किया। उनका मतलब अलग-अलग चीजों से है और प्रोग्रामर के पास अलग-अलग तरीकों से प्रत्येक पर अभिनय करने की क्षमता होनी चाहिए। यह तथ्य कि उन्होंने अपनी कार्यप्रणाली बदल दी है, मुझे बताता है कि उनके पास वास्तव में कोई सुराग नहीं है कि इन मूल्यों का इलाज कैसे किया जाना चाहिए।


"नल स्ट्रिंग" और NULL मान के बीच अंतर करने के लिए आवश्यक उद्धरण। ओरेकल को छोड़कर किसी भी डेटाबेस में, एक VARCHARफ़ील्ड का मान (शून्य या अधिक वर्ण) या कोई मान नहीं (NULL), पूर्ण विराम हो सकता है।

"पांच या छह साल पहले" 2011 से 10g समय सीमा (10.1 जारी 2003, 2005 में 10.2) में गिर जाएगा। 10g ने पूरी तरह से नल की हैंडलिंग में किसी भी वैश्विक परिवर्तन का परिचय नहीं दिया है, और इसके बीच NULLऔर अशक्त मूल्य के बीच कोई अंतर नहीं है , और इस तरह के अंतर का कोई मतलब नहीं है। मुझे डर है कि यह उत्तर पूर्ण कल्पना है।
विलियम रॉबर्टसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.