2011-01-07 146 views
2

我在Sql Server 2008中苦苦掙扎XML。我有一個xml文檔,我需要解析爲一個行集。我試圖想出一個簡單的查詢,當對BLOB執行,返回結果,如:從Xml輸入中返回行集

ID         Status 
--------        -------- 
3765aaf7-afaa-4a46-8499-5a61b607692c 0 
1234aaf7-afaa-4a46-8499-5a61b607692c 1 

下面是示例XML:

DECLARE @xml XML 

SET @xml = '<Batch xmlns="urn:mynamespace"> 
    <request xmlns:b="urn:mymessages"> 
    <b:Batches xmlns:c="urn:myentities"> 
     <c:BatchEntry> 
     <c:ID>3765aaf7-afaa-4a46-8499-5a61b607692c</c:ID> 
     <c:Status>0</c:Status> 
     </c:BatchEntry> 
     <c:BatchEntry> 
     <c:ID>1234aaf7-afaa-4a46-8499-5a61b607692c</c:ID> 
     <c:Status>1</c:Status> 
     </c:BatchEntry> 
    </b:Batches> 
    <b:BatchID>8492cbaa-eea5-479d-86c4-60cb62ac4b7c</b:BatchID> 
    </request> 
</Batch>' 

最接近我來是:

SELECT T.a.query('.') AS ID 
FROM @xml.nodes('/*[local-name() = "Batch"]/*[local-name() = "request"]/*[local-name() = "Batches"]/*[local-name() = "BatchEntry"]/*[local-name() = "ID"]/text()') T(a) 

但我無法弄清楚如何基本上選擇「批量」節點,然後返回一個行集每個「BatchEntry」。我覺得我只是不明白一些Sql Server xml操作員而已.. :)

您的幫助非常感謝!


UPDATE 2011-01-07

下面@IanC答案,我是能夠得到一個完整的工作情況,與XML命名空間中,我需要做的。我在這裏更新,以防其他人穿過它。

DECLARE @xml XML 

SET @xml = 
'<Batch xmlns="urn:mynamespace"> 
    <request xmlns:b="urn:mymessages"> 
    <b:Batches xmlns:c="urn:myentities"> 
     <c:BatchEntry> 
     <c:ID>3765aaf7-afaa-4a46-8499-5a61b607692c</c:ID> 
     <c:Status>0</c:Status> 
     </c:BatchEntry> 
     <c:BatchEntry> 
     <c:ID>1234aaf7-afaa-4a46-8499-5a61b607692c</c:ID> 
     <c:Status>1</c:Status> 
     </c:BatchEntry> 
    </b:Batches> 
    <b:BatchID>8492cbaa-eea5-479d-86c4-60cb62ac4b7c</b:BatchID> 
    </request> 
</Batch>' 

DECLARE @sp int 
DECLARE @hxml int 
DECLARE @Result int 

DECLARE @t table 
(
    ID UNIQUEIDENTIFIER, 
    BatchStatus INT 
) 

EXEC @sp = sp_xml_preparedocument @hxml OUTPUT, @xml 
, 
'<Batch 
    xmlns:a="urn:mynamespace" 
    xmlns:b="urn:mymessages" 
    xmlns:c="urn:myentities" 
/>' 

if @sp != 0 begin 
    SET @Result = '0' 
    RETURN 
end 

INSERT INTO @t 
SELECT * 
FROM OPENXML (@hxml, '/a:Batch/a:request/b:Batches/c:BatchEntry', 2) 
WITH 
(
    ID   UNIQUEIDENTIFIER 'c:ID', 
    BatchStatus INT     'c:Status' 
) 

SELECT * FROM @t 

EXEC sp_xml_removedocument @hxml; 

回答

2

試試這個作爲一般模式。如果您需要更多幫助,請告訴我,我將根據您的XML進行定製。

DECLARE @t table (
    ProductTypeID int, 
    LowMin   real, 
    HiMax   real, 
    ParamTypeID  int, 
    ParamWeight  real, 
    Low    real, 
    Hi    real, 
    Mode   tinyint   
) 

EXEC @sp = sp_xml_preparedocument @hxml OUTPUT, @XMLText 

if @sp != 0 begin 
    SET @Result = '0' 
    RETURN 
end 

INSERT INTO @t 
SELECT  * 
FROM  OPENXML (@hxml, '/query/product/param/item', 2) 
WITH  (
      ProductTypeID int  '../../@type', 
      LowMin   real '../@lowMin', 
      HiMax   real '../@hiMax', 
      ParamTypeID  int  '../@type', 
      ParamWeight  real '@weight', 
      Low    real '@low', 
      Hi    real '@hi', 
      Mode   tinyint '@mode' 
      ) 

EXEC sp_xml_removedocument @hxml; 
+0

作爲一個方面說明,OPENXML在這種類型的操作中速度明顯更快。 – IamIC 2011-01-07 06:46:39