2

私は T-SQL と XQuery の初心者です。

このような構造のDBにXML列があります

     <GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="...">
  <GP>
    <N>Amount1</N>
    <V i:type="X_AMT">
      <AMT>100001</AMT>
      <X_CODE>Dollar</X_CODE>
    </V>
  </GP>
  <GP>
    <N>Amount2</N>
    <V i:type="X_AMT">
      <AMT>0</AMT>
      <X_CODE />
    </V>
  </GP>
  <GP>
    <N>Amount3</N>
    <V i:type="X_AMT">
      <AMT>100001</AMT>
      <X_CODE>Dollar</X_CODE>
    </V>
  </GP>
  <GP>
    <N>Amount4</N>
    <V i:type="X_AMT">
      <AMT>0</AMT>
      <X_CODE />
    </V>
  </GP>
  <GP>
    <N>Amount5</N>
    <V i:type="X_AMT">
      <AMT>100001</AMT>
      <X_CODE>Dollar</X_CODE>
    </V>
  </GP>
  <GP>
    **<N>NeededAmount</N>**
    <V i:type="Y">
      <DETAILS>
        <REFERENCE>
          <N>**ReferenceName1**</N>
          <OId>111111</OId>
        </REFERENCE>
      </DETAILS>
      <DETAILS>
        <REFERENCE>
          <N>**ReferenceName2**</N>
          <OId>22222</OId>
        </REFERENCE>
      </DETAILS>
    </V>
  </GP>

  ...

  </GPC>

これは、私が使用している SQL Server のクエリです。クエリは、Name1 という名前を 1 つだけ返します。しかし、2 つの名前があり、100 の名前が存在する可能性があり、その名前を取得したいと考えています。

 SELECT v.Content.query(N'declare default element namespace "..."; 
    for $i in (GPC/GP) where ($i/N[1] eq "NeededAmount") return ($i)').value('declare default element namespace "..."; 
    (GP/V/DETAILS/REFERENCE/N)[1]', 'nvarchar(max)') AS NeededName
    FROM DB1.protected.WorkItem as v
    where v.Id = 1111

私の質問は、ドキュメント内のすべての名前を取得するためにこれを変更するにはどうすればよいですか? 誰かが私を助けることができますか?

前もって感謝します。

4

2 に答える 2

2

次のようなことを試してください:

;WITH XMLNAMESPACES(DEFAULT '...')
SELECT 
    Amount = XTbl.GP.value('(N)[1]', 'nvarchar(100)'),
    NeededName = XTbl2.DetRef.value('(N)[1]', 'nvarchar(200)')
FROM 
    Table1 AS t
CROSS APPLY
    t.XmlContent.nodes('/GPC/GP') AS XTbl(GP)
CROSS APPLY
    XTbl.GP.nodes('V/DETAILS/REFERENCE') AS XTbl2(DetRef)
WHERE 
    wi.Id = 1111
于 2012-12-12T13:57:16.950 に答える
0

nodes() Transact-SQL XML データ型メソッドを使用して、xml を行に「分割」する必要があります。nodes() メソッドは FROM 句で使用され、xml ドキュメント内の一致するノードごとに 1 行を生成します。

変数に格納された xml を使用した例を次に示します。

 DECLARE @x XML
 SET @x = N'     <GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" >
   <GP>
   <GP>
      <N>Amount5</N>
      <V i:type="X_AMT">
        <AMT>100001</AMT>
        <X_CODE>Dollar</X_CODE>
      </V>
   </GP>
   <GP>
      **<N>NeededAmount</N>**
      <V i:type="Y">
        <DETAILS>
           <REFERENCE>
             <N>**ReferenceName1**</N>
             <OId>111111</OId>
           </REFERENCE>
        </DETAILS>
        <DETAILS>
           <REFERENCE>
             <N>**ReferenceName2**</N>
             <OId>22222</OId>
           </REFERENCE>
        </DETAILS>
      </V>
   </GP>
   </GPC>
 '


 SELECT x.n.query('.') FROM @x.nodes('/GPC/GP/V/DETAILS/REFERENCE/N') AS x (n)
 /* returns 
 <N>**ReferenceName1**</N>
 <N>**ReferenceName2**</N> */

CROSS APPLY を使用して、テーブル内の xml 列を細断処理す​​ることもできます

 CREATE TABLE #t (id INT, doc XML)
 go
  DECLARE @x XML
 SET @x = N'     <GPC xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" >
   <GP>
      <N>Amount5</N>
      <V i:type="X_AMT">
        <AMT>100001</AMT>
        <X_CODE>Dollar</X_CODE>
      </V>
   </GP>
   <GP>
      **<N>NeededAmount</N>**
      <V i:type="Y">
        <DETAILS>
           <REFERENCE>
             <N>**ReferenceName1**</N>
             <OId>111111</OId>
           </REFERENCE>
        </DETAILS>
        <DETAILS>
           <REFERENCE>
             <N>**ReferenceName2**</N>
             <OId>22222</OId>
           </REFERENCE>
        </DETAILS>
      </V>
   </GP>
   </GPC>
 '
 INSERT INTO #t (id, doc) VALUES (1, @x)
 INSERT INTO #t (id, doc) VALUES (2, @x)


 SELECT t.id, x.n.query('.') RefName FROM #t t CROSS APPLY doc.nodes('/GPC/GP/V/DETAILS/REFERENCE/N') AS x (n)
 --returns 4 rows, 2 for each document
 /*
 id            RefName
 1     <N>**ReferenceName1**</N>
 1     <N>**ReferenceName2**</N>
 2     <N>**ReferenceName1**</N>
 2     <N>**ReferenceName2**</N> */
于 2012-12-12T14:13:05.133 に答える