Oracle, SQL Server, MySQL और SQLite में NULL और खाली-स्ट्रिंग सिमेंटिक्स को पोर्ट करना
Oracle, SQL Server, MySQL और SQLite में NULL हैंडलिंग को पोर्ट करने के लिए चार बिंदुओं पर ध्यान दें: NULL का परीक्षण कैसे किया जाता है, तुलना का परिणाम क्या होता है, बूलियन संदर्भ NULL को कैसे बदलते हैं, और खाली स्ट्रिंग का क्या अर्थ है। Oracle शून्य-लंबाई वाले वर्ण को NULL मानता है, जबकि SQL Server ANSI_NULLS पर निर्भर करता है।
इस पृष्ठ पर
मुख्य विचार
Oracle, SQL Server, MySQL और SQLite में NULL हैंडलिंग को पोर्ट करने के लिए चार पोर्टेबिलिटी बिंदुओं को ठीक करें: NULL का परीक्षण कैसे किया जाता है, NULL के विरुद्ध तुलना क्या लौटाती है, क्या बूलियन संदर्भ NULL को बाध्य (coerce) करते हैं, और खाली स्ट्रिंग का क्या अर्थ है। सबसे अधिक जोखिम वाला आइटम Oracle है, जो वर्तमान में शून्य लंबाई के वर्ण मान को null मानता है, लेकिन Oracle दस्तावेज़ चेतावनी देते हैं कि भविष्य के रिलीज़ में यह सच नहीं रह सकता है और अनुशंसा करते हैं कि खाली स्ट्रिंग को null के समान न माना जाए। परीक्षण के लिए IS NULL और IS NOT NULL का उपयोग करें, क्योंकि NULL से जुड़ी कोई भी अन्य स्थिति UNKNOWN के रूप में मूल्यांकित होती है, और UNKNOWN WHERE क्लॉज में लगभग FALSE की तरह व्यवहार करता है, लेकिन NOT UNKNOWN फिर से UNKNOWN ही रहता है। SQL Server एक कॉन्फ़िगरेशन ट्रेड-ऑफ जोड़ता है: SET ANSI_NULLS ON के साथ, एक या दो NULL ऑपरेंड UNKNOWN देते हैं, जबकि ANSI_NULLS OFF के साथ बराबर (=) और असमान (<>) ऑपरेटर NULL को एक ज्ञात मान के रूप में मानते हैं जो अन्य NULL के बराबर है और केवल TRUE या FALSE लौटाते हैं, जिससे सत्र सेटिंग्स के आधार पर फ़िल्टरिंग परिणाम बदल जाते हैं। MySQL NULL के साथ तुलनाओं को NULL लौटाना जारी रखता है, लेकिन इसका बूलियन संदर्भ 0 या NULL को false और किसी भी अन्य चीज़ को true मानता है, और यह GROUP BY में दो NULL को समान मानता है जबकि ASC ऑर्डरिंग पर NULL को पहले और DESC पर अंत में रखता है। SQLite संक्षिप्त IS और IS NOT ऑपरेटर प्रदान करता है जो हमेशा 1 या 0 लौटाते हैं और कभी NULL नहीं, लेकिन इसे SQLite एक्सटेंशन के रूप में दस्तावेज़ित करता है, जबकि मानक SQL के लिए इसके बजाय IS NOT DISTINCT FROM और IS DISTINCT FROM की आवश्यकता होती है। ट्रेड-ऑफ निरंतरता बनाम पोर्टेबिलिटी का है: इंजन-विशिष्ट रूप स्थानीय रूप से संक्षिप्त और पठनीय होते हैं, जबकि IS NULL / IS NOT NULL और स्पष्ट COALESCE-शैली हैंडलिंग ही एकमात्र ऐसा तरीका है जो हर जगह अनुमानित रूप से व्यवहार करता है। इन चार बिंदुओं को प्रति इंजन एक लिखित मैट्रिक्स के रूप में रिकॉर्ड करें, न कि यह मानकर कि मानक SQL व्यवहार लागू होगा, और PostgreSQL को एक पंक्ति के रूप में जोड़ें जिसे आप इसके अपने दस्तावेज़ों के विरुद्ध सत्यापित करें, क्योंकि यहाँ कोई PostgreSQL स्रोत उपलब्ध नहीं है।
संदर्भ और अनुशंसा
Oracle, SQL Server, MySQL और SQLite के बीच क्वेरी या साझा SQL मॉड्यूल को पोर्ट करने से पहले, NULL के लिए एक स्पष्ट पोर्टेबिलिटी चेकलिस्ट बनाएं: (1) NULL का परीक्षण कैसे किया जाता है, (2) NULL के विरुद्ध तुलना क्या लौटाती है, (3) क्या बूलियन संदर्भ NULL को बाध्य करते हैं, और (4) खाली स्ट्रिंग का क्या अर्थ है। सबसे अधिक जोखिम वाला आइटम Oracle है, जो वर्तमान में शून्य लंबाई के वर्ण मान को null मानता है, जबकि स्पष्ट रूप से अनुशंसा करता है कि आप खाली स्ट्रिंग्स के null के समान होने पर भरोसा न करें। इन चार बिंदुओं को प्रति इंजन एक लिखित मैट्रिक्स के रूप में रिकॉर्ड करें, न कि यह मानकर कि मानक SQL व्यवहार लागू होगा, और PostgreSQL को एक पंक्ति के रूप में जोड़ें जिसे आप इसके अपने दस्तावेज़ों के विरुद्ध सत्यापित करें, क्योंकि यहाँ कोई PostgreSQL स्रोत उपलब्ध नहीं है।
मुख्य पोर्टेबिलिटी नियम यह है कि NULL का परीक्षण केवल IS NULL और IS NOT NULL के साथ किया जाए। Oracle बताता है कि nulls के लिए उपयोग करने हेतु IS NULL और IS NOT NULL ही एकमात्र तुलनाएं हैं, null से जुड़ी कोई भी अन्य स्थिति UNKNOWN के रूप में मूल्यांकित होती है, और UNKNOWN WHERE में लगभग FALSE की तरह व्यवहार करता है लेकिन NOT UNKNOWN TRUE बनने के बजाय UNKNOWN ही रहता है। SQL Server में एक वास्तविक कॉन्फ़िगरेशन ट्रेड-ऑफ है: SET ANSI_NULLS ON के साथ, एक या दो NULL ऑपरेंड UNKNOWN देते हैं, जबकि ANSI_NULLS OFF के साथ बराबर और असमान ऑपरेटर NULL को एक ज्ञात मान के रूप में मानते हैं जो अन्य NULL के बराबर है और केवल TRUE या FALSE लौटाते हैं, जिससे सत्र सेटिंग्स के आधार पर फ़िल्टरिंग परिणाम बदल जाते हैं। MySQL NULL के साथ तुलनाओं को NULL लौटाना जारी रखता है, लेकिन इसका बूलियन संदर्भ 0 या NULL को false और किसी भी अन्य चीज़ को true मानता है, और यह GROUP BY में दो NULL को समान मानता है जबकि ASC ऑर्डरिंग पर NULL को पहले और DESC पर अंत में रखता है। SQLite संक्षिप्त IS और IS NOT ऑपरेटर प्रदान करता है जो हमेशा 1 या 0 लौटाते हैं और कभी NULL नहीं, लेकिन इसे SQLite एक्सटेंशन के रूप में दस्तावेज़ित करता है, जबकि मानक SQL के लिए इसके बजाय IS NOT DISTINCT FROM और IS DISTINCT FROM की आवश्यकता होती है।
ट्रेड-ऑफ निरंतरता बनाम पोर्टेबिलिटी का है: इंजन-विशिष्ट रूप स्थानीय रूप से संक्षिप्त और पठनीय होते हैं, जबकि IS NULL / IS NOT NULL और स्पष्ट COALESCE-शैली हैंडलिंग ही एकमात्र ऐसा तरीका है जो हर जगह अनुमानित रूप से व्यवहार करता है। यह न मानें कि एक इंजन के लिए लिखी गई क्वेरी दूसरे पर अपरिवर्तित चलेगी, और यह न मानें कि एक खाली स्ट्रिंग और एक NULL परस्पर विनिमेय हैं। मैट्रिक्स को प्रति इंजन चार बिंदुओं के साथ-साथ उन सत्र-स्तरीय सेटिंग्स को कैप्चर करना चाहिए जो परिणामों को बदल सकती हैं, और इसे एक बार के ऑडिट के बजाय कोड समीक्षा के लिए एक चेकलिस्ट के रूप में माना जाना चाहिए।
मैट्रिक्स के लिए स्रोत उद्धरणों को साक्ष्य के रूप में उपयोग करें: Oracle दस्तावेज़ कहते हैं कि केवल IS NULL और IS NOT NULL का उपयोग करें, nulls से जुड़ी कोई भी अन्य स्थिति UNKNOWN के रूप में मूल्यांकित होती है, UNKNOWN मूल्यांकन की एक स्थिति FALSE से इस मायने में भिन्न है कि UNKNOWN स्थिति मूल्यांकन पर आगे के संचालन UNKNOWN के रूप में मूल्यांकित होंगे, और Oracle वर्तमान में शून्य लंबाई वाले वर्ण मान को null मानता है लेकिन अनुशंसा करता है कि खाली स्ट्रिंग्स को null के समान न माना जाए। SQL Server दस्तावेज़ कहते हैं कि जब SET ANSI_NULLS ON होता है, तो एक ऑपरेटर जिसमें एक या दो NULL एक्सप्रेशन होते हैं, UNKNOWN लौटाता है, और जब SET ANSI_NULLS OFF होता है, तो बराबर और असमान ऑपरेटर NULL को एक ज्ञात मान के रूप में मानते हैं, जो किसी भी अन्य NULL के समकक्ष है, और केवल TRUE या FALSE लौटाते हैं। MySQL दस्तावेज़ दिखाते हैं कि 1 = NULL, 1 <> NULL, 1 < NULL और 1 > NULL सभी NULL लौटाते हैं, और 0 IS NULL 0 है जबकि '' IS NULL 0 है और '' IS NOT NULL 1 है। SQLite दस्तावेज़ कहते हैं कि IS या IS NOT एक्सप्रेशन के लिए NULL मूल्यांकित होना संभव नहीं है, संक्षिप्त रूप एक एक्सटेंशन हैं, और मानक SQL के लिए इसके बजाय IS NOT DISTINCT FROM और IS DISTINCT FROM की आवश्यकता होती है।
-- portable across the engines covered here
SELECT
'' IS NULL AS empty_is_null,
'' IS NOT NULL AS empty_is_not_null,
1 = NULL AS eq_null,
1 <> NULL AS ne_null;
-- run the same probe twice on SQL Server: once with ANSI_NULLS ON, once OFF
SET ANSI_NULLS ON;
SELECT 1 = NULL;
SET ANSI_NULLS OFF;
SELECT 1 = NULL;
-- row filtering: only this form is portable
SELECT * FROM t WHERE col IS NOT NULL;तर्क और ट्रेड-ऑफ
इंजन मूल नियम पर सहमत हैं लेकिन उन किनारों पर अलग हो जाते हैं जो पोर्टेबिलिटी को तोड़ते हैं। Oracle बताता है कि nulls के लिए उपयोग करने हेतु IS NULL और IS NOT NULL ही एकमात्र तुलनाएं हैं, null से जुड़ी कोई भी अन्य स्थिति UNKNOWN के रूप में मूल्यांकित होती है, और UNKNOWN WHERE में लगभग FALSE की तरह व्यवहार करता है लेकिन NOT UNKNOWN TRUE बनने के बजाय UNKNOWN ही रहता है। SQL Server में एक वास्तविक कॉन्फ़िगरेशन ट्रेड-ऑफ है: SET ANSI_NULLS ON के साथ, एक या दो NULL ऑपरेंड UNKNOWN देते हैं, जबकि ANSI_NULLS OFF के साथ बराबर और असमान ऑपरेटर NULL को एक ज्ञात मान के रूप में मानते हैं जो अन्य NULL के बराबर है और केवल TRUE या FALSE लौटाते हैं, जिससे सत्र सेटिंग्स के आधार पर फ़िल्टरिंग परिणाम बदल जाते हैं। MySQL NULL के साथ तुलनाओं को NULL लौटाना जारी रखता है, लेकिन इसका बूलियन संदर्भ 0 या NULL को false और किसी भी अन्य चीज़ को true मानता है, और यह GROUP BY में दो NULL को समान मानता है जबकि ASC ऑर्डरिंग पर NULL को पहले और DESC पर अंत में रखता है। SQLite संक्षिप्त IS और IS NOT ऑपरेटर प्रदान करता है जो हमेशा 1 या 0 लौटाते हैं और कभी NULL नहीं, लेकिन इसे SQLite एक्सटेंशन के रूप में दस्तावेज़ित करता है, जबकि मानक SQL के लिए इसके बजाय IS NOT DISTINCT FROM और IS DISTINCT FROM की आवश्यकता होती है।
ट्रेड-ऑफ निरंतरता बनाम पोर्टेबिलिटी का है: इंजन-विशिष्ट रूप स्थानीय रूप से संक्षिप्त और पठनीय होते हैं, जबकि IS NULL / IS NOT NULL और स्पष्ट COALESCE-शैली हैंडलिंग ही एकमात्र ऐसा तरीका है जो हर जगह अनुमानित रूप से व्यवहार करता है। इंजन-विशिष्ट रूप जैसे SQLite के IS और IS NOT संक्षिप्त हैं, लेकिन वे एक एक्सटेंशन हैं और उन इंजनों पर अपरिवर्तित नहीं चलेंगे जो केवल IS NOT DISTINCT FROM स्वीकार करते हैं। Oracle का खाली-स्ट्रिंग-एज़-नल व्यवहार संक्षिप्त है लेकिन संस्करण-संवेदनशील है, और Oracle दस्तावेज़ अनुशंसा करते हैं कि खाली स्ट्रिंग्स को null के समान न माना जाए। SQL Server की ANSI_NULLS सेटिंग चुपचाप = और <> के अर्थ को बदल सकती है, इसलिए एक क्वेरी जो पोर्टेबल दिखती है वह सत्र कॉन्फ़िगरेशन के आधार पर अलग-अलग पंक्तियाँ लौटा सकती है। MySQL का 0 और NULL का बूलियन बाध्यता false में लागू होता है बूलियन संदर्भों में, न कि = और <> तुलनाओं में, जो अभी भी NULL लौटाते हैं, इसलिए एक क्वेरी जो WHERE क्लॉज में काम करती है वह CASE एक्सप्रेशन या फंक्शन आर्गुमेंट में विफल हो सकती है।
इसलिए मैट्रिक्स को न केवल प्रोब्स के शाब्दिक परिणामों को बल्कि उन सत्र सेटिंग्स को भी रिकॉर्ड करना चाहिए जो उन्हें प्रभावित करती हैं। SQL Server के लिए, प्रोब चलाने से पहले वास्तविक ANSI_NULLS सेटिंग पढ़ें, क्योंकि कुछ कॉन्फ़िगरेशन में डिफ़ॉल्ट दस्तावेज़ित व्यवहार से भिन्न हो सकता है। Oracle के लिए, संस्करण रिकॉर्ड करें और अपग्रेड के बाद पुन: परीक्षण करें, क्योंकि खाली-स्ट्रिंग-एज़-नल नियम को भविष्य के रिलीज़ में बदलने योग्य के रूप में दस्तावेज़ित किया गया है। MySQL के लिए, बूलियन संदर्भों को तुलना ऑपरेटरों से अलग करें, और याद रखें कि ORDER BY ASC पर NULL को पहले और DESC पर अंत में रखता है। SQLite के लिए, याद रखें कि IS और IS NOT एक्सटेंशन हैं, और मानक SQL के लिए इसके बजाय IS NOT DISTINCT FROM और IS DISTINCT FROM की आवश्यकता होती है। मैट्रिक्स को यह भी रिकॉर्ड करना चाहिए कि क्या इंजन IS NOT DISTINCT FROM का समर्थन करता है, क्योंकि यह मानक SQL में NULL की समानता के लिए पोर्टेबल स्पेलिंग है।
अनुशंसा यह है कि ऐसी क्वेरी लिखें जो परीक्षण के लिए IS NULL और IS NOT NULL का उपयोग करें, और उन मानों के लिए स्पष्ट COALESCE या समकक्ष हैंडलिंग का उपयोग करें जो NULL हो सकते हैं। यह एकमात्र तरीका है जो हर जगह अनुमानित रूप से व्यवहार करता है, क्योंकि यह खाली स्ट्रिंग्स के इंजन उपचार, सत्र सेटिंग, या बूलियन संदर्भ पर निर्भर नहीं करता है। जब आपको खाली स्ट्रिंग को NULL से अलग करने की आवश्यकता हो, तो उन्हें अलग कॉलम में स्टोर करें या सेंटिनल वैल्यू का उपयोग करें, और इंजन के निहित रूपांतरण पर भरोसा न करें। मैट्रिक्स का उपयोग कोड समीक्षा के लिए एक चेकलिस्ट के रूप में किया जाना चाहिए, और जब भी कोई नया इंजन संस्करण दस्तावेज़ित व्यवहार को बदलता है तो इसे अपडेट किया जाना चाहिए।
ठोस उदाहरण
प्रत्येक लक्षित इंजन पर एक छोटा प्रोब चलाएं और पोर्टेबिलिटी प्रमाण के रूप में वास्तविक आउटपुट रिकॉर्ड करें: SELECT '' IS NULL, '' IS NOT NULL, 1 = NULL, 1 <> NULL, 0 = NULL; साथ ही एक बूलियन-कॉन्टेक्स्ट प्रोब जैसे SELECT NOT NULL उन इंजनों में चलाएं जो इसे बूलियन स्थिति में स्वीकार करते हैं। Oracle पर आपको खाली स्ट्रिंग NULL की तरह व्यवहार करती हुई दिखेगी, जबकि Oracle दस्तावेज़ चेतावनी देते हैं कि भविष्य के रिलीज़ में यह सच नहीं रह सकता है; MySQL '' IS NULL को 0 और '' IS NOT NULL को 1 के रूप में दस्तावेज़ित करता है, और 1 = NULL, 1 <> NULL के लिए NULL लौटाता है; SQLite NULL के बजाय IS और IS NOT से 1 या 0 लौटाता है। इसके बाद एक रो फ़िल्टर प्रोब, WHERE value <> NULL और WHERE value IS NOT NULL चलाएं, ताकि यह देखा जा सके कि प्रत्येक इंजन वास्तव में कौन सी पंक्तियाँ लौटाता है। प्रोब मानों को एक फिक्स्चर टेबल में रखें ताकि संग्रहीत खाली स्ट्रिंग्स बनाम NULLs के अंतर स्पष्ट रूप से दिखाई दें, न कि केवल अनुमानित हों।
फिक्स्चर टेबल में एक NULL, एक खाली स्ट्रिंग, एक शून्य और एक सामान्य मान होना चाहिए, और इसे एक अलग कॉपी में बनाया जाना चाहिए ताकि प्रोब उत्पादन डेटा को प्रभावित न करे। Oracle पर, खाली स्ट्रिंग को NULL के रूप में संग्रहीत किया जाता है, इसलिए प्रोब को '' IS NULL के रूप में 1 और '' IS NOT NULL के रूप में 0 दिखाना चाहिए, जबकि 1 = NULL और 1 <> NULL को NULL लौटाना चाहिए। MySQL पर, प्रोब को '' IS NULL के रूप में 0 और '' IS NOT NULL के रूप में 1 दिखाना चाहिए, जबकि 1 = NULL, 1 <> NULL, 1 < NULL और 1 > NULL सभी को NULL लौटाना चाहिए। SQLite पर, प्रोब को '' IS NULL के रूप में 0 और '' IS NOT NULL के रूप में 1 दिखाना चाहिए, जबकि 1 = NULL और 1 <> NULL को NULL लौटाना चाहिए, और IS और IS NOT को हमेशा 1 या 0 लौटाना चाहिए। SQL Server पर, प्रोब को दो बार चलाया जाना चाहिए, एक बार SET ANSI_NULLS ON के साथ और एक बार SET ANSI_NULLS OFF के साथ, क्योंकि जब ANSI_NULLS ON होता है तो equals और not-equals ऑपरेटर UNKNOWN लौटाते हैं और जब ANSI_NULLS OFF होता है तो TRUE या FALSE लौटाते हैं।
रो फ़िल्टर प्रोब यह दिखाना चाहिए कि प्रत्येक इंजन वास्तव में कौन सी पंक्तियाँ लौटाता है। WHERE value <> NULL को Oracle, MySQL और SQLite पर कोई पंक्ति नहीं लौटानी चाहिए, क्योंकि तुलना NULL लौटाती है और UNKNOWN के रूप में मूल्यांकित होने वाली स्थिति WHERE में लगभग FALSE की तरह कार्य करती है। WHERE value IS NOT NULL को उन सभी पंक्तियों को लौटाना चाहिए जो NULL नहीं हैं, और यह एकमात्र पोर्टेबल रूप है। SQL Server पर, यदि ANSI_NULLS OFF है, तो WHERE value <> NULL पंक्तियाँ लौटा सकता है, क्योंकि ऑपरेटर NULL को अन्य NULLs के बराबर एक ज्ञात मान के रूप में मानता है, इसलिए प्रोब को वास्तविक सत्र सेटिंग के साथ चलाया जाना चाहिए। बूलियन-कॉन्टेक्स्ट प्रोब यह दिखाना चाहिए कि NOT NULL उन इंजनों में UNKNOWN के रूप में मूल्यांकित होता है जो थ्री-वैल्यूड लॉजिक का पालन करते हैं, और UNKNOWN के साथ एक WHERE क्लॉज कोई पंक्ति नहीं लौटाता है, जबकि एक बूलियन कॉन्टेक्स्ट जो UNKNOWN को FALSE में बदलता है वह अलग तरह से व्यवहार कर सकता है।
प्रत्येक प्रोब के वास्तविक आउटपुट को मैट्रिक्स में रिकॉर्ड करें, और SQL Server के लिए सत्र सेटिंग शामिल करें। मैट्रिक्स को यह भी रिकॉर्ड करना चाहिए कि क्या इंजन IS NOT DISTINCT FROM का समर्थन करता है, और क्या खाली-स्ट्रिंग-एज़-नल नियम वर्तमान व्यवहार के रूप में दस्तावेज़ित है जो बदल सकता है। प्रोब परिणाम पोर्टेबिलिटी चेकलिस्ट के लिए प्रमाण हैं, और उनका उपयोग यह तय करने के लिए किया जाना चाहिए कि साझा SQL मॉड्यूल में किस स्पेलिंग का उपयोग करना है। पोर्टेबल स्पेलिंग IS NULL और IS NOT NULL के साथ स्पष्ट COALESCE-शैली का हैंडलिंग है, क्योंकि यह खाली स्ट्रिंग्स के इंजन उपचार, सत्र सेटिंग, या बूलियन कॉन्टेक्स्ट पर निर्भर नहीं करता है।
उपयोगिता सीमाएं
यह टिप केवल NULL तुलना और खाली-स्ट्रिंग सिमेंटिक्स को कवर करती है; यह NULLs की एग्रीगेट काउंटिंग, इंडेक्स व्यवहार, या प्रदर्शन को कवर नहीं करती है। स्रोतों में PostgreSQL दस्तावेज़ शामिल नहीं हैं, इसलिए यहाँ किसी PostgreSQL NULL या खाली-स्ट्रिंग व्यवहार का दावा नहीं किया गया है और मैट्रिक्स का विस्तार करने से पहले इसे PostgreSQL के अपने दस्तावेज़ों के विरुद्ध जांचा जाना चाहिए। Oracle का शून्य-लंबाई-कैरेक्टर नियम वर्तमान व्यवहार के रूप में दस्तावेज़ित है जो बदल सकता है, इसलिए इसे स्थायी गारंटी के बजाय एक संस्करण-संवेदनशील धारणा मानें जिसे अपग्रेड पर पुन: परीक्षण किया जाना चाहिए। SQL Server के परिणाम ANSI_NULLS सेटिंग पर निर्भर करते हैं, इसलिए डिफ़ॉल्ट मान मानने के बजाय वास्तविक सत्र कॉन्फ़िगरेशन की जांच करें। MySQL का 0 और NULL का बूलियन जबरन बदलाव (coercion) बूलियन कॉन्टेक्स्ट में लागू होता है, न कि = और <> तुलनाओं में, जो अभी भी NULL लौटाते हैं। SQLite के कॉम्पैक्ट IS और IS NOT फॉर्म एक एक्सटेंशन हैं, इसलिए उनका उपयोग करने वाला क्वेरी उन इंजनों पर बिना बदलाव के नहीं चलेगी जो केवल IS NOT DISTINCT FROM को स्वीकार करते हैं।
सीमाएं महत्वपूर्ण हैं क्योंकि मैट्रिक्स एक चेकलिस्ट है, गारंटी नहीं। Oracle का खाली-स्ट्रिंग-एज़-नल नियम भविष्य के रिलीज़ में बदलने की संभावना के रूप में दस्तावेज़ित है, इसलिए एक क्वेरी जो आज काम करती है वह अपग्रेड के बाद टूट सकती है। SQL Server की ANSI_NULLS सेटिंग = और <> के अर्थ को बदल सकती है, इसलिए एक क्वेरी जो पोर्टेबल दिखती है वह सत्र कॉन्फ़िगरेशन के आधार पर अलग-अलग पंक्तियाँ लौटा सकती है। MySQL का 0 और NULL का बूलियन जबरन बदलाव बूलियन कॉन्टेक्स्ट में लागू होता है, न कि = और <> तुलनाओं में, जो अभी भी NULL लौटाते हैं, इसलिए एक क्वेरी जो WHERE क्लॉज में काम करती है वह CASE एक्सप्रेशन या फंक्शन आर्गुमेंट में विफल हो सकती है। SQLite के कॉम्पैक्ट IS और IS NOT फॉर्म एक एक्सटेंशन हैं, इसलिए उनका उपयोग करने वाला क्वेरी उन इंजनों पर बिना बदलाव के नहीं चलेगी जो केवल IS NOT DISTINCT FROM को स्वीकार करते हैं। इसलिए मैट्रिक्स का उपयोग कोड समीक्षा के लिए एक चेकलिस्ट के रूप में किया जाना चाहिए, और जब भी कोई नया इंजन संस्करण दस्तावेज़ित व्यवहार को बदलता है तो इसे अपडेट किया जाना चाहिए।
मैट्रिक्स को यह भी रिकॉर्ड करना चाहिए कि क्या इंजन IS NOT DISTINCT FROM का समर्थन करता है, क्योंकि मानक SQL में NULLs की समानता के लिए यह पोर्टेबल स्पेलिंग है। यदि कोई इंजन इसका समर्थन नहीं करता है, तो पोर्टेबल स्पेलिंग IS NULL और IS NOT NULL के साथ स्पष्ट COALESCE-शैली का हैंडलिंग है। मैट्रिक्स का उपयोग एक इंजन से दूसरे इंजन के व्यवहार का अनुमान लगाने के लिए नहीं किया जाना चाहिए, और इसका उपयोग यह मानने के लिए नहीं किया जाना चाहिए कि एक खाली स्ट्रिंग और एक NULL विनिमेय हैं। प्रोब परिणाम पोर्टेबिलिटी चेकलिस्ट के लिए प्रमाण हैं, और उनका उपयोग यह तय करने के लिए किया जाना चाहिए कि साझा SQL मॉड्यूल में किस स्पेलिंग का उपयोग करना है। पोर्टेबल स्पेलिंग IS NULL और IS NOT NULL के साथ स्पष्ट COALESCE-शैली का हैंडलिंग है, क्योंकि यह खाली स्ट्रिंग्स के इंजन उपचार, सत्र सेटिंग, या बूलियन कॉन्टेक्स्ट पर निर्भर नहीं करता है।
स्रोतों में PostgreSQL दस्तावेज़ शामिल नहीं हैं, इसलिए यहाँ किसी PostgreSQL NULL या खाली-स्ट्रिंग व्यवहार का दावा नहीं किया गया है और मैट्रिक्स का विस्तार करने से पहले इसे PostgreSQL के अपने दस्तावेज़ों के विरुद्ध जांचा जाना चाहिए। मैट्रिक्स को कोड समीक्षा के लिए एक चेकलिस्ट के रूप में माना जाना चाहिए, और जब भी कोई नया इंजन संस्करण दस्तावेज़ित व्यवहार को बदलता है तो इसे अपडेट किया जाना चाहिए। प्रोब परिणाम पोर्टेबिलिटी चेकलिस्ट के लिए प्रमाण हैं, और उनका उपयोग यह तय करने के लिए किया जाना चाहिए कि साझा SQL मॉड्यूल में किस स्पेलिंग का उपयोग करना है। पोर्टेबल स्पेलिंग IS NULL और IS NOT NULL के साथ स्पष्ट COALESCE-शैली का हैंडलिंग है, क्योंकि यह खाली स्ट्रिंग्स के इंजन उपचार, सत्र सेटिंग, या बूलियन कॉन्टेक्स्ट पर निर्भर नहीं करता है।
उपयोग की शर्तें
- क्या लक्ष्य इंजन '' IS NULL को 0 और '' IS NOT NULL को 1 मानता है, या यह खाली स्ट्रिंग को NULL में बदल देता है?
- क्या 1 = NULL जैसी तुलना सत्र सेटिंग के आधार पर NULL, UNKNOWN, या TRUE/FALSE लौटाती है?
- क्या WHERE NOT NULL या IF(NOT NULL) जैसा बूलियन संदर्भ NULL को FALSE में बदलता है, या यह UNKNOWN को सुरक्षित रखता है?
- क्या इंजन का ORDER BY ASC पर NULL को पहले और DESC पर अंत में रखता है, या यह किसी अन्य नियम का पालन करता है?
- क्या GROUP BY दो NULL को समान मानता है, और क्या इंजन IS NOT DISTINCT FROM का समर्थन करता है?
- क्या खाली-स्ट्रिंग-एज़-नल नियम को वर्तमान व्यवहार के रूप में दस्तावेज़ित किया गया है जो भविष्य के रिलीज़ में बदल सकता है?
- क्या संक्षिप्त IS और IS NOT सिंटैक्स को मानक SQL के बजाय एक एक्सटेंशन के रूप में दस्तावेज़ित किया गया है?
- क्या परिणाम ANSI_NULLS जैसी सत्र-स्तरीय सेटिंग से प्रभावित होते हैं, और क्या आप प्रोब चलाने से पहले उस सेटिंग को पढ़ सकते हैं?
- क्या प्रोब फिक्स्चर संग्रहीत NULL को संग्रहीत खाली स्ट्रिंग से अलग करता है, या दोनों को एक ही माना जाता है?
- क्या आपने मैट्रिक्स को PostgreSQL इंजन तक विस्तारित करने से पहले PostgreSQL दस्तावेज़ों के विरुद्ध सत्यापित किया है?
उपयोग की सीमाएँ
यह टिप केवल NULL तुलना और खाली-स्ट्रिंग सिमेंटिक्स को कवर करती है; यह nulls की एग्रीगेट काउंटिंग, इंडेक्स व्यवहार, या प्रदर्शन को कवर नहीं करती है। स्रोतों में PostgreSQL दस्तावेज़ शामिल नहीं हैं, इसलिए यहाँ किसी PostgreSQL NULL या खाली-स्ट्रिंग व्यवहार का दावा नहीं किया गया है और मैट्रिक्स विस्तारित करने से पहले इसे PostgreSQL के अपने दस्तावेज़ों के विरुद्ध जाँचा जाना चाहिए। Oracle का शून्य-लंबाई-वर्ण नियम वर्तमान व्यवहार के रूप में दस्तावेज़ित है जो बदल सकता है, इसलिए इसे स्थायी गारंटी के बजाय संस्करण-संवेदनशील धारणा मानें जिसे अपग्रेड पर पुन: परीक्षण किया जाए। SQL Server के परिणाम ANSI_NULLS सेटिंग पर निर्भर करते हैं, इसलिए डिफ़ॉल्ट मान मानने के बजाय वास्तविक सत्र कॉन्फ़िगरेशन की जाँच करें। MySQL का 0 और NULL का बूलियन बाध्यता false में बूलियन संदर्भों में लागू होता है, न कि = और <> तुलनाओं में, जो अभी भी NULL लौटाते हैं। SQLite के संक्षिप्त IS और IS NOT रूप एक एक्सटेंशन हैं, इसलिए उनका उपयोग करने वाली क्वेरी उन इंजनों पर अपरिवर्तित नहीं चलेगी जो केवल IS NOT DISTINCT FROM स्वीकार करते हैं।