2012-08-10 7 views
5

मैं एक SELECT जो CASE का उपयोग करता है एक उचित प्रकार में nvarchar मान परिवर्तित करने के लिए कुछ इस तरह कर रहा हूँ,:मामला तब खंड हमेशा से मूल्यांकन

SELECT CASE 
    WHEN @propType = 'money' THEN convert(money, datavalue) 
    [...] 
    ELSE datavalue 
END 
FROM [...] 

हालांकि, ऐसा लगता convert हमेशा निष्पादित किया जाता है, तब भी जब @propType पैसे के बराबर नहीं है। चलने योग्य उदाहरण:

declare @proptype nvarchar(50)= 'nvarchar' 
declare @val nvarchar(10) = 'test' 
select 
    case @proptype 
     when 'money' then convert(money, @val) 
     else @val 
    end 

यह क्यों है, और मैं इसके आसपास कैसे हो सकता हूं?

मामला बयान इसकी स्थितियों से क्रमिक रूप से मूल्यांकन करता है और पहली शर्त जिसका शर्त पूरी होने के साथ बंद हो जाता है: MSDN प्रलेखीकरण इस कहते हैं। कुछ परिस्थितियों में, एक अभिव्यक्ति का मूल्यांकन CASE कथन से पहले किया जाता है, अभिव्यक्ति के परिणामों को इसके इनपुट के रूप में प्राप्त करता है। में त्रुटियों का मूल्यांकन इन अभिव्यक्तियों का मूल्यांकन करना संभव है। कुल अभिव्यक्तियां जब किसी CASE कथन के तर्कों का मूल्यांकन पहले किया जाता है, तो CASE कथन के लिए प्रदान किया जाता है। उदाहरण के लिए, निम्नलिखित क्वेरी MAX कुल के मान का उत्पादन करते समय शून्य त्रुटि से विभाजित करती है। यह CASE अभिव्यक्ति का मूल्यांकन करने से पहले होता है।

मुझे यकीन नहीं है कि यह प्रासंगिक है, लेकिन भाषा गैर-मूल के लिए कुछ हद तक भारी है, तो शायद यह है?

+0

स्पष्ट रूप से 'money' करने के लिए एक' varchar' परिवर्तित जब यह वापस 'varchar' को implicitely बदला न गया हो का एकमात्र उद्देश्य है, afaik शुरू करने के प्रयोजनों तो स्वरूपण कारण है कि आप या तो इसे आवश्यक स्वरूपण में स्टोर नहीं करते के लिए क्लाइंट को स्वरूपण को संभालने या उसके साथ जाने दें? –

+1

स्रोत डेटा मेरे नियंत्रण में नहीं है। वास्तविक मामले में मुझे डेटा को ऐसे प्रारूप में लाने के लिए कुछ हुप्स से कूदना है, जिसे मैं इसे रिपोर्ट तालिका में डाल सकता हूं जिसके लिए इसे नियत किया गया है (जिसे ठीक से टाइप किया गया है) – carlpett

उत्तर

3

निम्नलिखित Use caution when Using CONVERT() with CASE or IF functions in Transact SQL (T-SQL)

पहले विचार आम तौर पर में से एक हैं पर एक नज़र डालें निम्नलिखित "जब से पहले मूल्य का मूल्यांकन सांख्यिक है, यह दशमलव में परिवर्तित किया जाता है, और अन्य सभी डेटा की उम्मीद है दशमलव के साथ-साथ "OR" हो सकता है यदि SQL सर्वर किसी भी मान को निर्दिष्ट प्रकार में परिवर्तित करता है, तो सभी मान परिवर्तित प्रकार के होने की उम्मीद है "। हालांकि, यह सही नहीं है (हालांकि दूसरा बंद है)!

असली समस्या यह है कि अगर आप प्रकरण बयान के भीतर कहीं भी मूल्यों कन्वर्ट करने के लिए चुनते हैं, डेटाप्रकार आप मूल्यों परिवर्तित कर रहे हैं है करने के लिए सभी मूल्यों की उम्मीद प्रकार अगर वे कि प्रकार या के हैं की परवाह किए बिना है नहीं। इसके अलावा, भले ही मूल्यों में से कोई भी वास्तव में परिवर्तित हो सकता है (भले ही कोड की कनवर्ट लाइन कभी निष्पादित न हो), के सभी मान अब भी द्वारा निर्दिष्ट प्रकार के होने की उम्मीद है!

+0

धन्यवाद, यह क्यों प्रकाशित होता है, लेकिन वास्तव में इससे कोई रास्ता नहीं है? – carlpett

1

क्या हो रहा है then खंड मूल्यांकन नहीं किया जा रहा है के बारे में स्पष्ट रूप से कहें।

आप एक ही त्रुटि दिखाई देती है, तो आप कर

SELECT CASE @proptype 
     WHEN 'money' THEN $1.0 /*<-- Literal of datatype money*/ 
     ELSE @val 
     END 

CASE के लिए दस्तावेज़ वापसी प्रकार

रिटर्न कि result_expressions और वैकल्पिक में प्रकार के सेट से सर्वोच्च प्राथमिकता प्रकार बताते हैं else_result_expression। जानकारी के लिए, Data Type Precedence (Transact-SQL) देखें।

money उच्च डेटाप्रकार पूर्वता से nvarchar तो else @val तो मूल्यांकन किया जाता है कि money को डाल सकते हैं और विफल रहता हो जाता है।

एक संभावित कामकाज इसे sql_variant पर डालना होगा क्योंकि इसमें दोनों की तुलना में अधिक डेटा प्राथमिकता है।

declare @proptype nvarchar(50)= 'nvarchar' 
declare @val nvarchar(10) = 'test' 
select 
    case @proptype 
     when 'money' then convert(money, @val) 
     else cast(@val as SQL_VARIANT) 
    end 
संबंधित मुद्दे