2012-08-31 11 views
7

टीआई ISNULL() एक आलसी समारोह?क्या एसक्यूएल सर्वर का ISNULL() फ़ंक्शन आलसी/छोटा-सर्किट है?

है यही कारण है, अगर मैं निम्नलिखित की तरह कुछ कोड डाल दें:

SELECT ISNULL(MYFIELD, getMyFunction()) FROM MYTABLE

यह हमेशा getMyFunction() का मूल्यांकन करेंगे या यह केवल इस मामले में जहां MYFIELD वास्तव में शून्य है में इसका मूल्यांकन करेंगे?

+0

आप अपने फ़ंक्शन में 'प्रिंटर' कथन जोड़ सकते हैं और अपने लिए खोज सकते हैं। –

+0

@ जेरेटमेयर मैंने अपने बचपन के समय में प्रोग्रामिंग सीखने के लिए उस तकनीक का उपयोग किया, लेकिन यह आजकल लागू नहीं होता है क्योंकि आप नहीं जानते कि कार्यान्वयन विवरण क्या है और दस्तावेज व्यवहार क्या है। सीखना सामान कठिन हो रहा है :(बस कह रहा है ... –

+2

@ जेरेटमेयर, 'प्रिंटर' udf में स्वीकार्य नहीं है। – Kash

उत्तर

2

यह जो भी सोचता है वह सबसे अच्छा काम करेगा।

अब यह कार्यात्मक रूप से आलसी है, जो महत्वपूर्ण बात है। जैसे यदि col1 एक varchar जो हमेशा एक संख्या में शामिल होंगे जब col2, रिक्त है तो है

isnull(col2, cast(col1 as int)) 

काम करेगा।

हालांकि, यह निर्दिष्ट नहीं किया है कि क्या यह शून्य की जांच के साथ पहले या एक साथ कलाकारों की कोशिश और त्रुटि खाने अगर col2 रिक्त नहीं है जाएगा, या यदि केवल यही सब पर अगर col2 रिक्त है कलाकारों की कोशिश करेंगे।

कम से कम, हम उम्मीद करते हैं कि यह किसी भी मामले में col1 प्राप्त करेगी क्योंकि 2 मान प्राप्त करने वाली तालिका का एक स्कैन दो स्कैन से प्रत्येक को प्राप्त करने वाला तेज़ होगा।

समान SQL आदेशों को बहुत अलग तरीकों से निष्पादित किया जा सकता है, क्योंकि हमारे द्वारा दिए गए निर्देश इंडेक्स और तालिकाओं के आंकड़ों के आधार पर निम्न-स्तर के संचालन में परिवर्तित हो जाते हैं।

इसी कारण से, प्रदर्शन के संदर्भ में, जवाब "जब ऐसा लगता है कि यह एक अच्छा विचार होगा, अन्यथा यह नहीं है"।

मनाए गए व्यवहार के मामले में, यह आलसी है।

संपादित करें: माइकल एरिक्सन के उत्तर से पता चलता है कि ऐसे मामले हैं जो आलसी होने के कारण वास्तव में त्रुटि हो सकती हैं। मैं प्रदर्शन प्रभाव के संदर्भ में यहां अपने उत्तर से चिपके रहूंगा, लेकिन कम से कम कुछ मामलों में शुद्धता प्रभाव के मामले में उनका महत्वपूर्ण है।

+0

आप इस तथ्य की एक अच्छी व्याख्या देते हैं कि यह आलसी निर्भर हो सकता है या नहीं सर्वर के अनुकूलन निर्णयों पर आईएनजी। धन्यवाद। – eidylon

+0

आपका स्वागत है। हालांकि मैं एक चेतावनी जोड़ दूंगा। –

3

SELECT ISNULL(1, 1/0) 

SELECT ISNULL(NULL, 1/0) 

पहले का चयन देता है 1 के विभिन्न व्यवहार से परखने के बाद, दूसरा एक Msg 8134, Level 16, State 1, Line 4 Divide by zero error encountered. त्रुटि को जन्म देती है।

+0

यह पूरी तरह से भरोसेमंद नहीं है। विभिन्न पुनरीक्षण नियमों के चलते सबक्वायरी परेशानी का कारण बन सकती हैं। – usr

+0

@usr, वे अगर पहली फ़ील्ड हमेशा शून्य हो तो त्रुटि स्थिति उत्पन्न नहीं होगी। यह कहना नहीं है कि सर्वर 1/0 की गणना नहीं कर रहा है और फिर त्रुटि को खा रहा है जब यह देखता है कि अभिव्यक्ति का उपयोग नहीं किया जाता है - यह है –

+0

@ जोनहन्ना, हाँ मेरी टिप्पणी को संभावित प्रदर्शन मुद्दों पर निर्देशित किया गया था। – usr

2

यह "आलसी" विशेषता जिसका आप उल्लेख कर रहे हैं वास्तव में "शॉर्ट-सर्किटिंग"
कहा जाता है और यह हमेशा काम नहीं करता है अगर आपके पास ISNULL अभिव्यक्ति में udf है।
चेक इस लेख जहां परीक्षण यह साबित करने के लिए चलाए गया:
Short-circuiting (mainly in VB.Net and SQL Server)

T-SQL .. एक कथात्मक भाषा इसलिए यह परिणाम प्राप्त करने के लिए प्रयोग किया जाता एल्गोरिथ्म नियंत्रित नहीं कर सकते है यह सिर्फ वाणी क्या परिणाम यह की जरूरत है। लागत प्रभावी योजना का पता लगाने के लिए यह क्वेरी इंजन/ऑप्टिमाइज़र तक है। और SQL सर्वर में, ऑप्टिमाइज़र "विरोधाभास का पता लगाने" का उपयोग करता है जो प्रक्रियात्मक भाषाओं में आपके द्वारा बाएं से दाएं मूल्यांकन की गारंटी नहीं देगा।


अपने उदाहरण के लिए, एक त्वरित परीक्षण किया:
शून्य त्रुटि द्वारा फूट डालो आह्वान करने के लिए अदिश-मान यूडीएफ निर्मित:

CREATE FUNCTION getMyFunction 
(@MyValue INT) 
RETURNS INT 
AS 
BEGIN 
    RETURN (1/0) 
END 
GO 

नीचे दिए गए क्वेरी मुझे एक Divide by zero error encountered त्रुटि नहीं दिया रनिंग ।

DECLARE @test INT 
SET @test = 1 
SET @test = ISNULL(@test, (dbo.getMyFunction(1))) 
SELECT @test 

नीचे बयान के SET बदलने मुझे Divide by zero error encountered. त्रुटि किया था। (ISNULL में एक SELECT शुरू की)

SET @test = ISNULL(@test, (SELECT dbo.getMyFunction(1))) 

लेकिन चर के बजाय मूल्यों के साथ, यह कभी नहीं मुझे त्रुटि दे दी है।

SELECT ISNULL(1, (dbo.getMyFunction(1))) 
SELECT ISNULL(1, (SELECT dbo.getMyFunction(1))) 

तो जब तक आप वास्तव में यह पता लगाने की कैसे अनुकूलक सभी क्रमपरिवर्तन के लिए इन भाव मूल्यांकन कर रही है, यह T-SQL का शॉर्ट सर्किट क्षमताओं पर भरोसा नहीं करने के लिए सुरक्षित होगा।

4

यह ठीक

declare @X int 
set @X = 1 
select isnull(@X, 1/0) 

काम करता है लेकिन एक समग्र शुरू यह असफल और दूसरा तर्क साबित पहले से पहले का मूल्यांकन किया जा सकता है कि, कभी कभी कर देगा।

declare @X int 
set @X = 1 
select isnull(@X, min(1/0)) 
+0

कुल मिलाकर अच्छा स्थान। –

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