Domanda

Environment: SQL Server 2012.

Say I have a table Message with xml column WordIndex. I also have a table Word which has WordId and WordText. Xml for Message.WordIndex has the following schema:

<xs:schema attributeFormDefault="unqualified"
           elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.example.com">
    <xs:element name="wi">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="w">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element maxOccurs="unbounded" name="p" type="xs:unsignedByte" />
                        </xs:sequence>
                        <xs:attribute name="wid" type="xs:unsignedByte" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

and some data to go with it:

<wi xmlns="http://www.example.com">
  <w wid="1">
    <p>28</p>
    <p>72</p>
    <p>125</p>
  </w>
  <w wid="4">
    <p>89</p>
  </w>
  <w wid="5">
    <p>11</p>
  </w>
</wi>

I also have SQL queries with XQuery code like this:

with WordIds as
(
    select distinct
        t.c.value('@wid', 'int') as XmlWordId
    from
        Message as m
        cross apply
            m.WordIndex.nodes('/wi/w') as t(c)
    inner join Word as w
        on w.WordId = t.c.value('@wid', 'int')

-- some more joins go here ...
)
select
    count(*)
from
    WordIds

and this (this one doesn't work, since I started to introduce schema into it):

with xmlnamespaces('http://www.example.com' as ns)
select
    wi.Position,
    w.WordId,
    w.WordText
from
(
    select
        t.c.value('.', 'int') as Position,
        t.c.value('../@wid', 'int') as WordId
    from
        Message as m
        cross apply m.WordIndex.nodes('//p') as t(c)
    where
        m.MessageId = @MessageId
) as wi
inner join Word as w
    on w.WordId = wi.WordId
order by
    wi.Position

Question:

What is the proper syntax to qualify arguments to calls to .value() and .nodes()? I get errors that I don't fully understand:

XQuery [Message.WordIndex.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:anyAtomicType *'
È stato utile?

Soluzione

Try these queries:

;with xmlnamespaces( default 'http://www.example.com'), WordIds as 
( 
    select distinct 
        t.c.value('@wid', 'int') as XmlWordId 
    from 
        Message as m 
        cross apply 
            m.WordIndex.nodes('/wi/w') as t(c) 
    inner join Word as w 
        on w.WordId = t.c.value('@wid', 'int') 

-- some more joins go here ... 
) 
select 
    count(*) 
from 
    WordIds 


;with xmlnamespaces( default 'http://www.example.com')
select 
    w.c.value('@wid', 'INT') wid,
    p.c.value('.', 'INT') p
from message m
    cross apply m.wordIndex.nodes('wi/w') w(c)
        cross apply w.c.nodes('p') p(c)

Generally, try and avoid the parent axis(..) as it has performance issues. Instead use multiple CROSS APPLY to drill down into the xml left to right.

Have a look through this article for more info on namespaces:

Adding Namespaces Using WITH XMLNAMESPACES

http://msdn.microsoft.com/en-us/library/ms177400.aspx

Altri suggerimenti

It's just one of the syntactic rules, quote from:

http://msdn.microsoft.com/en-us/library/ms175972.aspx

"When a CTE is used in a statement that is part of a batch, the statement before it must be followed by a semicolon."

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top