SQL सर्वर CASE कथन सभी स्थितियों का मूल्यांकन करता है या पहले TRUE स्थिति पर बाहर निकलता है?


44

क्या SQL सर्वर (2008 या 2012, विशेष रूप से) CASEकथन सभी WHENस्थितियों का मूल्यांकन करता है या क्या यह एक बार एक ऐसा WHENखंड निकलता है जो सत्य का मूल्यांकन करता है? यदि यह शर्तों के पूरे सेट से गुज़रता है, तो क्या इसका मतलब यह है कि अंतिम स्थिति का मूल्यांकन वास्तविक अधिलेखित करता है कि सच का मूल्यांकन करने वाली पहली शर्त क्या है? उदाहरण के लिए:

SELECT
    CASE
        WHEN 1+1 = 2 THEN'YES'
        WHEN 1+1 = 3 THEN 'NO'
        WHEN 1+1 = 2 THEN 'NO' 
    END

परिणाम "YES" है, भले ही अंतिम हो जब स्थिति को "NO" का मूल्यांकन करना चाहिए। ऐसा लगता है कि यह पहली बार TRUE स्थिति प्राप्त करने के बाद बाहर निकलता है। किसी की पुष्टि करें कर सकते हैं अगर यह है मामला


5
बहुत निकटता से संबंधित: क्या SQL सर्वर किसी COALESCE फ़ंक्शन को पढ़ता है, भले ही पहला तर्क NULL न हो? (जैसा COALESCE()कि एक CASEअभिव्यक्ति में अनुवादित है ।)
ypercube

जवाबों:


46

पहली input_expression के result_expression को लौटाता है = जब TRUE का मूल्यांकन करता है

संदर्भ http://msdn.microsoft.com/en-us/library/ms181765.aspx


यह मानक SQL व्यवहार है:

  • एक CASEअभिव्यक्ति पहली वास्तविक स्थिति का मूल्यांकन करती है।

  • यदि कोई सही स्थिति नहीं है, तो यह ELSEभाग का मूल्यांकन करता है ।

  • यदि कोई वास्तविक स्थिति नहीं है और कोई ELSEहिस्सा नहीं है , तो इसका मूल्यांकन किया जाता है NULL


2
मैं सिर्फ यह सुनिश्चित करना चाहता था कि अगर मेरे पास 3 मामले की स्थिति है जो सभी सही मूल्यांकन करेंगे, तो मैं केवल पहले एक का काम करना चाहता हूं जो कि सही होने के लिए मूल्यांकन करता है और अन्य 2 नहीं (भले ही वे भी सच का मूल्यांकन करें )। मेरे प्रश्नों में उदाहरण क्वेरी से ऐसा प्रतीत होता है। मैं सिर्फ पुष्टि करना चाहता था। मैं यह भी उम्मीद कर रहा था कि SQL ऊपर से नीचे तक CASE शर्तों को पढ़ता है। धन्यवाद!
जुआन वेलेज़

15

SQL सर्वर आमतौर पर CASE स्टेटमेंट्स ( SQLFiddle ) के लिए शॉर्ट-सर्किट मूल्यांकन करता है :

--Does not fail on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 1 THEN 'Case 1'
      WHEN 2/0 = 1 THEN 'Case 2'
   END;

--Fails on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 99 THEN 'Case 1'
      WHEN 2/0 = 99 THEN 'Case 2'
   END;  

हालाँकि कई प्रकार के कथन हैं कि SQL Server 2012 के रूप में शॉर्ट-सर्किट सही ढंग से नहीं है। टिप्पणी में ypercube से लिंक देखें।

ऑरेकल हमेशा शॉर्ट-सर्किट मूल्यांकन करता है11.2 SQL भाषा संदर्भ देखें । या निम्नलिखित ( SQLFiddle ) की तुलना करें :

--Does not fail on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 1 THEN 'Case 1'
    WHEN 2/0 = 1 THEN 'Case 2'
  END
FROM dual;


--Fails on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 99 THEN 'Case 1'
    WHEN 2/0 = 99 THEN 'Case 2'
  END
FROM dual;

यह वही परीक्षण MySQL के साथ नहीं किया जा सकता है क्योंकि यह शून्य से विभाजन के लिए शून्य देता है। ( एसक्यूएल फिडेल )


इस बारे में कैसे ?: SQL-Fiddle
ypercube '30

1
Field SQL-Server के बारे में है । यह हारून का जवाब है: क्या SQL सर्वर सभी फ़ंक्शन को पढ़ता है, भले ही पहला तर्क NULL न हो?
ypercube y

@ypercube वास्तव में दिलचस्प व्यवहार है। यह उस कोड का मूल्यांकन कर रहा है जो दूसरे हिस्से में चलेगा, लेकिन यह इस बात को नजरअंदाज करने पर निर्भर करता है कि अन्य कौन से भाव मौजूद हैं और क्या शून्य से भाग एक MIN के अंदर है या नहीं। Sqlfiddle.com/# -6
Leigh Riffel

@ypercube अब जब मैंने आपके द्वारा पोस्ट किए गए कुछ लिंक को पढ़ा है, तो क्या आप कहेंगे कि यह कहने के लिए पर्याप्त किनारे मामले हैं कि SQL सर्वर शॉर्ट-सर्किट मूल्यांकन करता है या नहीं - आमतौर पर इसका जवाब है?
लेह रिफ़ेल

3
हां, मैं "आमतौर पर" पर सहमत होता हूं। जैसा कि हारून अपने जवाब में बताते हैं, एक परीक्षण "CASE हमेशा शॉर्ट-सर्किट" को बाधित करने के लिए पर्याप्त है। लेकिन यह आमतौर पर होता है।
ypercube y

7

ऐसा प्रतीत होता है कि MS SQL सर्वर शॉर्ट-सर्किट मूल्यांकन का भी उपयोग करता है।

निम्नलिखित परीक्षण में मेरे पास 3 परीक्षण हैं। पहला हमेशा सच होता है, दूसरा टेबल को संदर्भित किए बिना विफल रहता है, और तीसरा केवल तभी विफल होता है जब डेटा को ध्यान में रखा जाता है।
इस विशेष रन में दोनों पंक्तियों को सफलतापूर्वक लौटाया जाता है। अगर मैं पहली WHEN, या पहली और दूसरी टिप्पणी करता हूं तो मुझे असफलताएं मिलती हैं।

CREATE TABLE casetest (test varchar(10))
GO
INSERT INTO casetest VALUES ('12345'),('abcdef')
GO

SELECT CASE WHEN LEN(test)>1 THEN test
        WHEN 1/0 = 1 THEN 'abc'
        WHEN CAST(test AS int) = 1 THEN 'def'
        END
FROM casetest
GO

1

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

declare @tbl table(id int)
insert into @tbl values(1)
insert into @tbl values(2)
insert into @tbl values(3)

--Fails on the divide by zero.
SELECT * FROM @tbl
where  CASE 
        WHEN id = 2 THEN 1 -- first row in table will not satisfy the condition
        WHEN 2/0 = 1 THEN 1
        ELSE 0
      END =1

-- when filter the records to only who will staisfy the first case when condition, it 
will not fail on the divide by zero
SELECT * FROM @tbl
where ID=2 and -- first row in table will  satisfy the condition
  CASE 
    WHEN id = 2 THEN 1
    WHEN 2/0 = 1 THEN 1
    ELSE 0
  END =1

1

MySQL में यह पहले सही विकल्प पर केस स्टेटमेंट से बाहर निकल जाएगा। यदि आपके पास कई सच्चे मूल्यों की संभावना है, तो आप पहले से दिए गए उत्तर को अनुक्रम में रखना चाहते हैं।


प्रश्न SQL सर्वर के बारे में है।
जेम्स एंडरसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.