0

環境: SQL Server 2012。

xml 列 WordIndex を持つテーブル Message があるとします。WordId と WordText を持つテーブル Word もあります。Message.WordIndex の Xml には、次のスキーマがあります。

<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>

それに付随するいくつかのデータ:

<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>

次のような XQuery コードを使用した SQL クエリもあります。

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

そしてこれ(スキーマを導入し始めたので、これは機能しません):

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

質問:

.value() および .nodes() への呼び出しの引数を修飾する適切な構文は何ですか? 完全には理解できないエラーが表示されます。

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

2 に答える 2

2

次のクエリを試してください。

;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)

一般に、パフォーマンスの問題があるため、親軸 (..) は避けてください。代わりに、複数の CROSS APPLY を使用して、xml を左から右にドリルダウンします。

名前空間の詳細については、この記事をご覧ください。

WITH XMLNAMESPACES を使用した名前空間の追加

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

于 2012-09-09T19:56:43.910 に答える
1

これは構文規則の 1 つにすぎません。以下から引用します。

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

「バッチの一部であるステートメントで CTE を使用する場合、その前のステートメントの後にセミコロンを付ける必要があります。」

于 2012-09-09T20:41:23.430 に答える