2011-12-11 13 views
5

मैं कुछ एसक्यूएल सर्वर में exist() और value() तरीकों 2008एसक्यूएल सर्वर एक्सएमएल मौजूद हैं()

मेरे एक्सएमएल इस तरह दिखता है का उपयोग कर समस्या है:

<?xml version="1.0" encoding="UTF-8"?> 
<library> 
    <branches> 
     <branch> 
      <codelib>1</codelib> 
      <name>Campus</name> 
     </branch> 
     <branch> 
      <codelib>2</codelib> 
      <name>47th</name> 
     </branch> 
     <branch> 
      <codelib>3</codelib> 
      <name>Mall</name> 
     </branch>    
    </branches> 
    <books> 
     <book type="SF"> 
      <codb>11</codb> 
      <title>Robots</title> 
      <authors> 
       <author>author1 robots</author> 
       <author>author2 robots</author> 
      </authors> 
      <price>10</price> 
      <stocks> 
       <branch codelib="1" amount="10"/> 
       <branch codelib="2" amount="5"/> 
       <branch codelib="4" amount="15"/> 
      </stocks> 
      <from>20</from> 
      <to>30</to> 
     </book> 
     <book type="poetry"> 
      <codb>12</codb> 
      <title>Poetry book</title> 
      <authors> 
       <author>AuthorPoetry</author> 
      </authors> 
      <price>14</price> 
      <stocks> 
       <branch codelib="1" amount="7"/> 
       <branch codelib="2" amount="5"/> 
      </stocks> 
      <from>25</from> 
      <to>40</to> 
     </book>  
     <book type="children"> 
      <codb>19</codb> 
      <title>Faitytales</title> 
      <authors>    
       <author>AuthorChildren</author>    
      </authors> 
      <price>20</price> 
      <stocks> 
       <branch codelib="1" amount="10"/> 
       <branch codelib="3" amount="55"/> 
       <branch codelib="4" amount="15"/> 
      </stocks> 
      <from>70</from> 
      <to>75</to> 
     </book>  
     <book type="literature"> 
      <codb>19</codb> 
      <title>T</title> 
      <authors> 
       <author>A</author>     
      </authors> 
      <price>17</price> 
      <stocks> 
       <branch codelib="1" amount="40"/> 
      </stocks> 
      <from>85</from> 
      <to>110</to> 
     </book> 
    </books> 
</library> 

इस एक्सएमएल देखते हुए, मैं एक लिखने के लिए है SELECT खंड जो query(), value() और exist() प्रत्येक बार 2 बार उपयोग करेगा। मैं और exist() का उपयोग SELECT में भी नहीं कर सकता, क्योंकि ऐसा लगता है कि WHERE खंड का कोई प्रभाव नहीं पड़ता है।

उदाहरण के लिए, मैं सभी <branch> तत्वों है कि प्रकार SF के साथ पुस्तक के बच्चे हैं प्राप्त करना चाहते हैं, लेकिन चुनिंदा बयान

declare @genre varchar(15) 
    set @genre = 'SF' 
    SELECT XMLData.query('//branch') from TableA 
    WHERE XMLData.exist('//book[./@type = sql:variable("@genre")]') = 1 

सभी <branch> तत्वों, लक्षित से न सिर्फ लोगों को पुन: प्राप्त किताब। मैं यह नहीं समझ सकता कि मेरे चयन में क्या गलत है। इसके अलावा, मैं query(), exist() और value() एक ही चयन में (? यह संभव एसक्यूएल एक्सएमएल में चुनिंदा बयान नेस्ट की है, है)

उत्तर

7

खैर, अपने XPath यहाँ अभिव्यक्ति "अपराधी" है के साथ एक छोटा सा उदाहरण का स्वागत करेंगे:

query('//branch') 

यह कहता है: सभी<branch> पूरे दस्तावेज़ से नोड्स का चयन करें। यह सिर्फ वही कर रहा है जो आप इसे करने के लिए कह रहे हैं, वास्तव में ....

इस प्रश्न के साथ क्या गलत है ??

SELECT 
    XMLData.query('/library/books/book[@type=sql:variable("@genre")]//branch') 
FROM dbo.TableA 

कि <book> नोड है कि type="SF" विशेषता के रूप में के लिए सभी <branch> subnodes पुनः प्राप्त होगा ....

आप एक ही बयान में अपने query(), exist() और value() सभी के साथ प्राप्त करने के लिए कोशिश कर रहे हैं ?? काफी संभवतः, इसे बहुत आसान किया जा सकता है ....

इसके अलावा: मुझे लगता है कि आप SQL Server XQuery में .exist() क्या गलत व्याख्या कर रहे हैं। नहीं लागू करने - - आप मेज से पंक्तियों का चयन कर रहे

SELECT (some columns) 
FROM dbo.TableA 
WHERE XMLData.exist('//book[@type = sql:variable("@genre")]') = 1 

आप मूल रूप से एसक्यूएल सर्वर कह रहे हैं dbo.TableA से सभी पंक्तियों को पुनः प्राप्त करने के जहां एक्सएमएल XMLData में जमा एक <book type=.....> नोड शामिल हैं: आप यहाँ अपने बयान है, तो XMLData कॉलम की सामग्री का चयन ...

+0

ऐसा नहीं है कि मैं चाहता हूं, लेकिन मुझे एक ही कथन में क्वेरी(), मान() और मौजूद() दोनों का उपयोग करना होगा। यही कारण है कि मैं टी-एसक्यूएल में कुछ प्रकार की फ़िल्टरिंग करना चाहता हूं, चुनें ... कहां ... अगर संभव हो तो नेस्टेड SELECT स्टेटमेंट की तरह कुछ हो सकता है। मैं सिर्फ – joanna

3

आपके द्वारा प्रदान किया गया एक्सएमएल खुद को exist कथन में उधार नहीं देता है। यदि आपके पास एकाधिक एक्सएमएल स्टेटमेंट थे और उसमें एक ऐसा स्थान ढूंढने के लिए जरूरी था जहां इसमें कुछ मूल्य था, तो कथन अधिक प्रासंगिक होगा।

where खंड आप की आपूर्ति की बस अगर हालत मौजूद है की जाँच करता है और अगर यह होता है, सब branches तत्वों, का चयन करता है सिर्फ एक जहां हालत सच है नहीं। उदाहरण के लिए, निम्नलिखित (जाहिर है) वापसी नहीं है कुछ भी:

SELECT @xmldata.query('//branch') from TableA 
WHERE @xmldata.exist('//book[./@type = "BLAH"]') = 1 

लेकिन यहाँ आप सभी तीन एक में बयान चयन का उपयोग कर सकते दिखाने के लिए कुछ न कुछ है।

SELECT T.c.query('./title').value('.', 'varchar(250)') as title, 
     T.c.exist('.[@type eq "SF"]') as IsSF 
    from @xmldata.nodes('//book') T(c) 
+0

जैसे smth को प्राप्त करने के तरीके पर एक उदाहरण चाहता हूं कि आपके द्वारा प्रदान किया गया चयन मुझे जो चाहिए, उसके करीब है, tnx। एक आखिरी समस्या ... क्या कुछ चुनना संभव है ... जहां x = (चयन करें .. कहीं भी), ताकि मैं मान(), मौजूद() और क्वेरी() 2 बार उपयोग कर सकूं? असल में, एक चयन (सभी 3 कार्यों के साथ) जो कुछ मान फ़िल्टर करेगा, और फिर फ़िल्टर किए गए नोड्स का उपयोग करने वाला दूसरा? – joanna

0

क्षमा करें अगर यह देर हो चुकी है लेकिन मैंने केवल इस पोस्ट को देखा है।

यह आवश्यक नोड को फ़िल्टर करने के लिए क्रॉस लागू ऑपरेटर का उपयोग करके फ़िल्टर करने के लिए XML के साथ अधिक कुशल है, फिर लौटा नोड्स से क्वेरी का चयन करें। बच्चे नोड्स से पूछताछ करने के लिए आपको रूट को भी शामिल करने की आवश्यकता है। इस मामले में क्वेरी में। // शाखा के बजाय .//branch।

declare @genre varchar(15) = 'SF' 
select l.query('.//branch') from TableA 
cross apply XmlData.nodes('library/books/book[@type=sql:variable("@genre")]') n (l) 

तुम अब भी जोड़ सकते हैं खंड मौजूद है अगर आप चाहते हैं, लेकिन यह वास्तव में अतिरिक्त अनावश्यक भूमि के ऊपर

WHERE XMLData.exist('//book[./@type = sql:variable("@genre")]') = 1 

आशा इस मदद करता है जोड़ देगा। डी

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