2012-10-18 9 views
9

SQL Server 2008を使用して解析する必要があるXMLがいくつかあります。私が望むものに近づいていると思いますが、正しい構文がありません。SQL ServerでXML要素を選択

私は次があります。

DECLARE @doc XML 
SET @doc = '<ROOT>   
    <InvoiceDetail> 
     <OrderId>1000000</OrderId> 
     <OrderTypeId>2</OrderTypeId> 
     <Id>2000</Id> 
     <InvoiceItems> 
      <InvoiceItem> 
       <LineId>1</LineId> 
       <Cd>123456</Cd> 
       <Description>Item 1</Description> 
       <Quantity>1</Quantity> 
       <UnitPrice>99.990000</UnitPrice> 
      </InvoiceItem> 
      <InvoiceItem> 
       <LineId>2</LineId> 
       <Cd>234567</Cd> 
       <Description>Item 2</Description> 
       <Quantity>1</Quantity> 
       <UnitPrice>89.990000</UnitPrice> 
      </InvoiceItem> 
     </InvoiceItems> 
    </InvoiceDetail> 
    <InvoiceDetail> 
     <OrderId>1200000</OrderId> 
     <OrderTypeId>1</OrderTypeId> 
     <Id>3000</Id> 
     <InvoiceItems> 
      <InvoiceItem> 
       <LineId>1</LineId> 
       <Cd>234567</Cd> 
       <Description>Item 2</Description> 
       <Quantity>1</Quantity> 
       <UnitPrice>89.990000</UnitPrice> 
      </InvoiceItem> 
      <InvoiceItem> 
       <LineId>2</LineId> 
       <Cd>345678</Cd> 
       <Description>Item 3</Description> 
       <Quantity>1</Quantity> 
       <UnitPrice>79.990000</UnitPrice> 
      </InvoiceItem> 
     </InvoiceItems> 
    </InvoiceDetail> 
</ROOT>' 

SELECT 
     Invoices.Node.value('@OrderId', 'VARCHAR(10)') 'OrderID' 
    , Invoices.Node.value('@Id', 'INT') 'InvoiceId' 
    , Items.Cd.value('.', 'VARCHAR(14)') 'ItemId' 
FROM 
    @doc.nodes('//InvoiceDetail') Invoices(Node) 
    CROSS APPLY Invoices.Node.nodes('./InvoiceItems/InvoiceItem/Cd') Items(Cd) 

私は次のような結果を得る:

NULL NULL 123456 
NULL NULL 234567 
NULL NULL 234567 
NULL NULL 345678 

私は次のことを取得しようとしている:私は間違って

1000000 2000 123456 
1000000 2000 234567 
1200000 3000 234567 
1200000 3000 345678 

何をしています?要素をつかむため

+1

+1簡単にテスト可能/再生可能な例 –

答えて

6

構文は次のとおりです。

SELECT Invoices.Node.value('(OrderId)[1]', 'VARCHAR(10)') 'OrderID' 
    , Invoices.Node.value('(Id)[1]', 'INT') 'InvoiceId' 
    , Items.Cd.value('.', 'VARCHAR(14)') 'ItemId' 
FROM 
    @doc.nodes('//InvoiceDetail') Invoices(Node) 
    CROSS APPLY Invoices.Node.nodes('./InvoiceItems/InvoiceItem/Cd') Items(Cd) 

これは、明示的な括弧なしで動作するように表示されます。

Invoices.Node.value('OrderId[1]', 'VARCHAR(10)') 

@構文は属性ではなく、XQueryの中の要素のためであります。ここで

SELECT Invoices.Node.value('@title', 'VARCHAR(MAX)') AS Title 
FROM @doc.nodes('//InvoiceDetail') Invoices(Node) 

をもあなたのデータとうまく動作しますXQuery value

+0

おかげでアダムのための指導や外部リンクのため。 – jared

0

次のSQLを使用しての良い記事がある:あなたが

<InvoiceDetail title="something"> 

を持っていたなら、あなたは使用していることを照会することができるようになります。

-- Iterate through each of the "ROOT\InvoiceDetail" records in our XML 
SELECT 
    x.Rec.query('./OrderId').value('.', 'nvarchar(2000)') AS 'OrderID', 
    x.Rec.query('./Id').value('.', 'nvarchar(2000)') AS 'ID', 
    items.cd.query('./Cd').value('.', 'nvarchar(2000)') AS 'ItemID' 
FROM @doc.nodes('/ROOT/InvoiceDetail') as x(Rec) 
CROSS APPLY x.Rec.nodes('./InvoiceItems/InvoiceItem') Items(Cd) 

これにより、次の結果が得られます。

enter image description here

(構文はしかし不可解ですが、それではありません!)