2010-01-21 9 views
9

जब मैं इस क्वेरीसबक्वायरी में "अवैध कॉलम नाम XYZ" त्रुटि क्यों नहीं; हालांकि स्तंभ नाम subquery तालिका में नहीं है?

SELECT CustomerId FROM Stocks.dbo.Suppliers 

यह मुझे इस त्रुटि देता है चलाते हैं। अमान्य स्तंभ नाम 'ग्राहक आईडी'। यह त्रुटि मान्य है क्योंकि प्रदायक तालिका में कोई कॉलम ग्राहक आईडी नहीं है; लेकिन जब मैं subquery में एक ही क्वेरी का उपयोग करता हूं तो यह कोई त्रुटि नहीं देता है उदा।

SELECT * 
    FROM SomeOtherDb.dbo.Customer 
WHERE CustomerId In(SELECT CustomerId 
         FROM Stocks.dbo.Suppliers) 

यहां मुझे एक ही त्रुटि "अवैध कॉलम नाम" की उम्मीद है, लेकिन क्वेरी बिना किसी त्रुटि के चलती है।

पूरी तरह से योग्य नाम सिर्फ सम्मेलन है दोनों डीबीएस एक ही सर्वर पर हैं।

ग्राहक आईडी कुछOtherDb.dbo.Customer तालिका में मौजूद है लेकिन subquery में नहीं है।

यह व्यवहार क्यों है? क्या यह सबकुछ के साथ है?

धन्यवाद।

+0

या तो स्थिति में मुझ पर अमान्य स्तंभ त्रुटि फेंकता। पूरी तरह से योग्य नाम सिर्फ सम्मेलन या एक लिंक सर्वर के माध्यम से है? – Andrew

+0

पूरी तरह से योग्य नाम सिर्फ एक सम्मेलन है। दोनों डीबी एक ही सर्वर पर हैं। – Kashif

उत्तर

13

सबक्वायरी बाहरी प्रश्नों से कॉलम प्राप्त करते हैं।

मुझे लगता है कि आपके SomeOtherDb.dbo.Customer के पास ग्राहक आईडी कॉलम है (जो नामों से भी संभवतः लगता है)।

जो तब भी संभवतः इसका मतलब है कि आप उस सबक्वायरी के साथ नहीं कर रहे हैं जो आप इसके साथ करना चाहते हैं - यदि सबक्वायरी में तालिका में ग्राहक आईडी कॉलम नहीं है (और ऐसा लगता है, अन्यथा कोई त्रुटि नहीं होगी स्वयं में subquery चला रहा है), तो subquery बाहरी ग्राहक आईडी चुनता है और देता है, और चूंकि यह subquery में एकमात्र कॉलम है, subquery बेकार है।

+0

हाँ आप सही हैं SomeOtherDb.dbo. ग्राहक के पास ग्राहक आईडी कॉलम है। – Kashif

+6

मैंने इसे अपने आप में कुछ बार चलाया है, और हालांकि उत्तर समझ में आता है, मुझे लगता है कि यह SQL सर्वर में खराब डिज़ाइन है (चाहे वह एक आईएसओ एसक्यूएल मानक को पूरी तरह कार्यान्वित कर रहा हो)। मुझे लगता है कि माता-पिता की क्वेरी में कॉलम का संदर्भ देते समय उपनामों को उपनामों का उपयोग करने के लिए अधिक सुरक्षित होना आवश्यक होगा। मेरे सहयोगी को एक संबंधित त्रासदी का अनुभव हुआ जब उसने गलती से उपरोक्त की तरह उपखंड में टाइपो के कारण उत्पादन तालिका में सभी पंक्तियों को अद्यतन किया। Hilarity (और बैकअप से बहाल) ensued :) –

+0

प्रत्येक कॉलम के लिए तालिका (या तालिका उपनाम) को स्पष्ट रूप से परिभाषित करके एक अच्छी प्रैक्टिस है: यह आपकी सबक्वायरीज़ को गलत तालिकाओं से कॉलम प्राप्त करने से बचने के लिए, और नियमित रूप से जुड़ने पर भी (उपकुंजी के बिना) अगर कोई नया कॉलम बनाता है तो नाम विवादों से बच जाएगा। – drizin

1

आपके प्रश्न का उत्तर ("क्यों कोई त्रुटि नहीं है") ऊपर है, लेकिन भविष्य में इस प्रकार के मुद्दे से बचने के तरीके पर थोड़ी सी मदद हो सकती है: ऐसा करने के लिए एक सबक्वायरी का उपयोग करने के बजाय, बाएं शामिल हों:

SELECT C.* 
FROM SomeOtherDb.dbo.Customer AS C 
LEFT JOIN Stocks.dbo.Suppliers AS S ON C.CustomerId = S.CustomerId 
WHERE S.CustomerID Is Null 

यह क्वेरी, जब संभवतः एक जॉइन के साथ बनाया गया हो, तो हमेशा आपके मूल या बेहतर प्रदर्शन करेगा - और आपके ऊपर उपरोक्त उस समस्या से बचने का अतिरिक्त लाभ है। क्योंकि इस निर्माण में आप स्वाभाविक रूप से टेबल नामों का उपयोग करेंगे, जब कोई समस्या हो, तो यह अधिक स्पष्ट होगा, समान चिह्न के दोनों तरफ एक ही तालिका का नाम। सबक्विरी चूसते हैं, मैं उनके खिलाफ एक स्थायी क्रूसेड पर हूं।

(कि ने कहा, मैं जानता हूँ कि बहुत से लोग अलियासिंग के खिलाफ एक धर्मयुद्ध है, जो मैं ऊपर उपयोग को आसान बनाने के/कोड गाढ़ा :) पर हैं)