2013-07-19 5 views
12

क्या nodes()xml डेटा प्रकार दस्तावेज़ दस्तावेज़ में डेटा प्रकार रिटर्न नोड्स की विधि है?क्या 'नोड्स()' विधि दस्तावेज़ ऑर्डर रखती है?

उदाहरण के लिए

, अगर वहाँ की तरह डेटा कर रहे हैं:

declare @xml xml 
set @xml = '<Fruits><Apple /><Banana /><Orange /><Pear /></Fruits>' 

जो

select T.c.query('.') 
from @xml.nodes('/Fruits/*') T(c) 

के रूप में क्वेरी की जाती है तत्वों दस्तावेज़ क्रम में लौटा दी जाएगी? select द्वारा लौटाई गई पंक्तियों का आदेश अपरिभाषित माना जाता है यदि order by खंड छोड़ा गया है। क्या यह select ... from ... .nodes() के मामले में है, या यह असाधारण है?

declare @xml xml 
set @xml = '<Data><Element OrderNo="1" /><Element OrderNo="2" />' 
    + '<Element OrderNo="3" /><Element OrderNo="4" />' 
    + '<Element OrderNo="5" /></Data>' 

select * from (
    select T.c.value('.', 'int') OrderNo1, 
     row_number() over (order by @@spid) OrderNo2 
    from @xml.nodes('/Data/Element/@OrderNo') T(c)) sq 
where OrderNo1 != OrderNo2 

उत्तर

19

हाँ, nodes() एक पंक्ति दस्तावेज़ क्रम में सेट उत्पन्न करता है:

यह संभव कुछ परिस्थितियों इस क्वेरी का उत्पादन में गैर खाली rowset प्राप्त करने के लिए है। ऐसा करने के लिए क्वेरी प्लान में प्रयुक्त ऑपरेटर Table Valued Function XML Reader है।

टेबल-मान समारोह एक्सएमएल रीडर एक पैरामीटर के रूप में एक XML ब्लॉब इनपुट और एक पंक्ति सेट XML दस्तावेज़ क्रम में एक्सएमएल नोड्स का प्रतिनिधित्व पैदा करता है। अन्य इनपुट पैरामीटर एक्सएमएल दस्तावेज़ के सबसेट में लौटाए गए एक्सएमएल नोड्स को प्रतिबंधित कर सकते हैं।

लेकिन order by के बिना एक प्रश्न अनिर्धारित आदेश है इसलिए कोई गारंटी नहीं है।

का उपयोग करने के लिए row_number() over() खंड में तालिका मूल्यवान फ़ंक्शन द्वारा उत्पन्न id का उपयोग करने का एक तरीका है और क्रम में जेनरेट किए गए नंबर का उपयोग करें।

select X.q 
from 
    (
    select T.c.query('.') as q, 
     row_number() over(order by T.c) as rn 
    from @xml.nodes('/Fruits/*') T(c) 
) as X 
order by X.rn 

यह एक order by सीधे में T.c उपयोग करने के लिए संभव नहीं है। कोशिश कर रहा है कि आप

संदेश 493, स्तर 16, राज्य 1, रेखा 19
स्तंभ 'सी' कि नोड्स से लौटाए गए दे देंगे() विधि सीधे नहीं किया जा सकता। इसका उपयोग केवल चार एक्सएमएल डेटा प्रकार विधियों में से एक के साथ किया जा सकता है, मौजूद(), नोड्स(), क्वेरी(), और वैल्यू(), या आईएस न्यूल में और नल चेक नहीं है।

त्रुटि में यह उल्लेख नहीं किया गया कि इसे row_number के साथ काम करना चाहिए, लेकिन यह करता है और यह बहुत अच्छा हो सकता है जो ठीक हो सकता है ताकि उपरोक्त कोड विफल हो जाए। लेकिन एसक्यूएल सर्वर 2012 तक यह ठीक काम करता है।

row_number के अनियंत्रित उपयोग पर भरोसा किए बिना गारंटीकृत आदेश प्राप्त करने का एक तरीका उन संख्याओं की एक तालिका का उपयोग करना होगा जहां आप स्थिति द्वारा नोड्स निकालते हैं।

select T.c.query('.') as q 
from Numbers as N 
    cross apply @xml.nodes('/Fruits/*[sql:column("N.Number")]') as T(c) 
where N.Number between 1 and @xml.value('count(/Fruits/*)', 'int') 
order by N.Number 
+2

जबकि मैंने इस पोस्ट को ऊपर उठाया (क्योंकि इसमें विषय पर मैंने जो जानकारी देखी है उसका सबसे अच्छा संग्रह है), यह माइक्रोसॉफ्ट के एसक्यूएल कार्यान्वयन में एक निश्चित छेद है। ओरेकल, डीबी 2 और पोस्टग्रेएसक्यूएल (कम से कम) में XMLTables में ऑर्डिनेलिटी कॉलम हैं। मुझे टी-एसक्यूएल (गैर-एएनएसआई) एक्सएमएल एक्सटेंशन का उपयोग करके कुछ चीजें आसान मिलती हैं; एएनएसआई-शैली एसक्यूएल/एक्सएमएल के साथ अन्य चीजें आसान हैं। ज्यादातर यह एक धो है।लेकिन यह एक स्पष्ट विकल्प है जिसमें कोई साफ विकल्प नहीं है (उन्होंने कहा, एमएस सुन रहा था)। – unbob

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