2012-10-18 41 views
9

我有一些XML需要使用SQL Server 2008进行解析。我想我已经接近取得我想要的东西,但我没有正确的语法(我相信)。在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中没有的元素。如果你有

<InvoiceDetail title="something"> 

然后你就可以查询,使用:

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

下面是关于使用XQuery value

+0

感谢亚当的指导和外部链接。 – jared

0

下面的SQL也将与您的数据很好地工作的好文章:

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

(语法是莫名其妙,虽然,不是吧!)