2012-11-01 15 views
5

कारण मैं इस तरह के दृश्य उपलब्ध हैं:कहां देखें उर्फ ​​पर त्रुटि

SELECT location, CAST(SUBSTRING(location, 9, 4) AS int) AS ProcessCode 
FROM dbo.asset 
WHERE (status NOT IN ('INACTIVE', 'NOT READY', 'LIMITEDUSE')) 
AND (location LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_') 

तो मैं इसे इस तरह कहते हैं, यह काम करता है:

SELECT * FROM FooView 

हालांकि, अगर मैं एक कहां खंड जोड़ें:

Conversion failed when converting the varchar value '-01-' to data type int.

:
SELECT * FROM FooView WHERE ProcessCode > 0 

मैं इस त्रुटि मिलती है

क्यों? चूंकि स्थान 1-2-100-0800-A प्रारूप में होना चाहिए, इसलिए मुझे नहीं लगता कि रूपांतरण त्रुटि कैसे हो सकती है। क्या यह संभव है कि CASTWHERE से पहले विफल रहता है परिणाम फ़िल्टर करने का मौका? यदि हां, तो पहली क्वेरी क्यों काम करती है?

संपादित करें - काम के आसपास

मैं सिर्फ एक सह कार्यकर्ता का सुझाव एक अच्छा काम के आसपास था। यह काम करता है, लेकिन यह अभी भी व्याख्या नहीं करता है कि प्रारंभिक समस्या क्यों है।

यह ProcessCode के लिए चयन में है:

CASE WHEN location LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_' 
THEN CAST(SUBSTRING(location, 9, 4) AS int) ELSE 0 END AS ProcessCode, 
+0

ब्याज से एसक्यूएल सर्वर का कौन सा संस्करण? और कॉलम प्रकार क्या स्थान है? –

+0

एसक्यूएल सर्वर 2012. स्थान वक्रार (24) है। –

उत्तर

4
साथ

इस

+०१२३५१६४१० को अपना दृश्य बदलें
SELECT location, 
     CASE WHEN SUBSTRING(location, 9, 4) > '' 
      AND SUBSTRING(location, 9, 4) NOT LIKE '%[^0-9]%' THEN 
       CAST(SUBSTRING(location, 9, 4) AS int) END AS ProcessCode 
    FROM dbo.asset 
WHERE (status NOT IN ('INACTIVE', 'NOT READY', 'LIMITEDUSE')) 
    AND (location LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_') 

देखें इस Connect item

एसक्यूएल सर्वर आदेश है कि यह फैसला करता है अनुकूलित है में कहां/SELECT खंड का मूल्यांकन करने के लिए स्वतंत्र है। एक दृश्य जब तक इंडेक्स दृश्य के रूप में भौतिक रूप से बाहरी क्वेरी में विस्तारित नहीं किया जाता है, तो आपका WHERE खंड वास्तव में दृश्य में सुव्यवस्थित किया जा रहा है, यानी।

SELECT * FROM FooView WHERE ProcessCode > 0 
-- is really seen as 
SELECT location, CAST(SUBSTRING(location, 9, 4) AS int) AS ProcessCode 
FROM dbo.asset 
WHERE (status NOT IN ('INACTIVE', 'NOT READY', 'LIMITEDUSE')) 
AND (location LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_') 
AND CAST(SUBSTRING(location, 9, 4) AS int) > 0 ---- << Expanded inline 

क्योंकि अभिव्यक्ति दोनों का चयन करें और कहां खंड के लिए इस्तेमाल किया जाता है, यह एसक्यूएल सर्वर मूल पुनः प्राप्ति में पहली SELECT खंड में अभिव्यक्ति को हल करने का फैसला किया है लगता है। क्वेरी निष्पादन योजना देखने के लिए इसे आसानी से Ctrl-L का उपयोग करके देखा जा सकता है। आप देखेंगे कि SQL सर्वर एक ही समय में तालिका से एक पुनर्प्राप्ति करता है, जिसमें 2 अभिव्यक्तियां होती हैं, location और CAST(SUBSTRING(location, 9, 4) AS int) होती हैं।

+0

धन्यवाद। यह मेरे प्रश्न में काम के आसपास कुछ हद तक है। मेरा संपादन देखें। हालांकि यह एक कार्य विकल्प प्रदान करता है, यह मूल व्यवहार की व्याख्या नहीं करता है। –

+0

मैंने एक स्पष्टीकरण जोड़ा है। साथ ही, आपका कामकाज कुछ हद तक डेटा-निर्भर है क्योंकि आप उस बिट का परीक्षण नहीं कर रहे हैं जिसे कास्ट किया जा रहा है बल्कि कॉलम डेटा का पैटर्न है। – RichardTheKiwi

+0

जो व्यवहार को समझाएगा। यदि WHERE को खराब डेटा फ़िल्टर करने का मौका मिलने से पहले चयन का मूल्यांकन किया जा रहा है, तो इससे त्रुटि हो जाएगी। क्या आप यही कह रहे हैं? –

0

डाली जहां से पहले विफल रहता है, हाँ। दरअसल, कास्ट स्वयं से पहले विफल हो रहा है, अगर मुझे गलत नहीं लगता है, तो तालिका को देखने के ठीक बाद और स्थान कॉलम के नीचे सबस्ट्रिंग का आकार निर्धारित करता है।

आपको लगता है कि सबस्ट्रिंग वापस लौटने के लिए एक गलत अनुमान है, क्योंकि यदि आप कहते हैं कि प्रारूप वास्तव में 1-2-100-0800-ए है, तो सब्सट्रिंग (str, 9, 4) 0800 वापस आना चाहिए , लेकिन यह '-1-' लौट रहा है, जो एक आईएनटी नहीं है।

छोटे में अपने बयान काटना। मैं पहले सब्सट्रिंग के परिणाम में देखता हूं।

आशा व्यक्त की कि मदद की।

+1

धन्यवाद, लेकिन मुझे नहीं लगता कि मैं अनुमान लगा रहा हूं कि सबस्ट्रिंग क्या देता है। मुझे लगता है कि पूरा मुद्दा यह है कि कहां फ़िल्टर से पहले कास्ट हो रहा है, लेकिन मैं गलत हो सकता था। यदि ऐसा है, तो पहली क्वेरी क्यों काम करती है? –

1

यह Sql सर्वर 2008, कुछ और फैशनेबल हो रहा है पर काम करता है ...

create view myview 
AS 
SELECT CAST(SUBSTRING('1-2-100-0800-A', 9, 4) AS int) as ProcessCode 
Where '1-2-100-0800-A' LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_' 

GO 

SELECT * FROM myview WHERE ProcessCode > 0 

यहाँ बेला>http://sqlfiddle.com/#!3/3bcfd/2

संपादित है निष्पादन के आदेश हो सकता है के रूप में नीचे का सुझाव दिया, कोशिश यह एक में (आईडी के साथ अनुकूलित)

SELECT location, CAST(SUBSTRING(location, 9, 4) AS int) AS ProcessCode 
FROM dbo.asset 
Where id in(
select id 
from dbo.asset 
WHERE (status NOT IN ('INACTIVE', 'NOT READY', 'LIMITEDUSE')) 
AND (location LIKE '[1-6]-[12]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-_') 
) 
+0

मुझे लगता है कि यह काम करता है क्योंकि आप केवल एक के साथ परीक्षण कर रहे हैं, अच्छा मूल्य। वहां अन्य, बुरे मूल्य हैं जिन्हें WHERE क्लॉज के माध्यम से हटाया जाना चाहिए। –

+0

क्या आप "खराब" मान का उदाहरण दे सकते हैं? –

+0

निश्चित रूप से, जो भी नियमित रूप से विस्तारित नहीं होता है: ALM00-00-06, 1-5-RMT, 1-0-DEV। –

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