2012-10-18 13 views
9

Mam trochę XML, które muszę analizować przy użyciu SQL Server 2008. Myślę, że jestem blisko uzyskania tego, co chcę, ale nie mam poprawnej składni (jak sądzę).Wybierz element XML w SQL Server

mam następujące:

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) 

uzyskać następujące wyniki:

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

próbuję uzyskać następujące:

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

Co robię źle ?

+1

+1 za łatwo sprawdzalne/powtarzalny przykład –

Odpowiedz

6

Składnia do zgrywania element jest:

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) 

To również wydaje się działać bez wyraźnej nawiasie:

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

Składnia @ jest dla atrybutów, a nie elementy XQuery . Jeśli miał

<InvoiceDetail title="something"> 

Wtedy można zapytać, że za pomocą:

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

Tu jest dobry artykuł na temat korzystania XQuery value

+0

Dzięki Adam za kierunkiem i linku zewnętrznego. – jared

0

następujących SQL będzie również działać dobrze z danymi:

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

Daje nam to następujące wyniki:

enter image description here

(Składnia jest kłopotliwe, choć nie jest to!)

Powiązane problemy