2017-03-08 100 views
1

我試圖從我的XML中提取一個值,似乎在掙扎。希望有人能幫助從SQL Server 2008中的XML屬性獲取價值使用OPENXML

這裏是我的XML

 '<Transfer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <Products> 
     <Product TUT="true" ID="38319223176264031724"> 
      <Identifier>38319223176264031724</Identifier> 
      <ProductItemCode>83192</ProductItemCode> 
      <Qty>1</Qty> 
      <NetWeight>23.100</NetWeight> 
      <GrossWeight>23.684</GrossWeight> 
      <SerialNumber>317</SerialNumber> 
      <ECertItemNumber>2</ECertItemNumber> 
      <Markets Type="ECERT"> 
       <Market>EU</Market> 
       <Market>US</Market> 
      </Markets> 
      <Attribute Name="PackDate">2016-09-20T00:00:00</Attribute> 
      <Attribute Name="PlantID">124</Attribute> 
      <Attribute Name="SlgrDate">2016-09-19T00:00:00</Attribute> 
     </Product> 
     <Product TUT="true" ID="28319219766306010024"> 
      <Identifier>28319219766306010024</Identifier> 
      <ProductItemCode>83192</ProductItemCode> 
      <Qty>1</Qty> 
      <NetWeight>19.700</NetWeight> 
      <GrossWeight>20.284</GrossWeight> 
      <SerialNumber>100</SerialNumber> 
      <ECertItemNumber>2</ECertItemNumber> 
      <Markets Type="ECERT"> 
       <Market>EU</Market> 
       <Market>US</Market> 
      </Markets> 
      <Attribute Name="PackDate">2016-11-01T00:00:00</Attribute> 
      <Attribute Name="PlantID">124</Attribute> 
      <Attribute Name="SlgrDate">2016-10-31T00:00:00</Attribute> 
     </Product> 
</Products> 
    </Transfer>' 

我想提取是標識符,ProductItemCode,淨重,毛重,及PackDate和SlgrDate的屬性值。

我可以很容易地得到所有的字段除了PackDate的屬性值和SlgrDate

這裏是我的字段代碼

if OBJECT_ID('tempdb..#XmlImportTest') is not null 
drop table #XmlImportTest 


CREATE TABLE #XmlImportTest(
xmlFileName VARCHAR(300) NOT NULL, 
xml_data XML NOT NULL 
) 
GO 

DECLARE @xmlFileName VARCHAR(3000) 

SELECT @xmlFileName = 'K:\Upload\CSNXML\WaybillXml.xml' 


--– dynamic sql is just so we can use @xmlFileName variable in OPENROWSET 

EXEC('INSERT INTO #XmlImportTest(xmlFileName, xml_data) 

SELECT ''' + @xmlFileName + ''', xmlData 
FROM(
SELECT * 
FROM OPENROWSET (BULK ''' + @xmlFileName + ''', SINGLE_BLOB) AS XMLDATA 
) AS FileImport (XMLDATA) 
') 
GO 


DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX) 


select @xml = (SELECT xml_data from #XmlImportTest) 

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML 


SELECT Identifier as barcode,ProductItemCode as standpack,SerialNumber, NetWeight netwt_ind, GrossWeight grosswt_ind 
FROM OPENXML (@hDoc, '/Transfer/Products/Product',2) 
WITH (Identifier varchar(80), 
ProductItemCode varchar(10), 
SerialNumber varchar(48), 
NetWeight decimal(13,2), 
GrossWeight decimal(13,2) 
) 


exec sp_xml_removedocument @hDoc 

XML文件包含相同的XML提供 樣本現在我不知道如何從每個產品的屬性中獲取價值。

我在SQL SERVER 2008

回答

1

使用可選的ColPattern運行這個指定的XPath到你想要的節點。

FROM OPENXML (@hDoc, '/Transfer/Products/Product',2) 
WITH (
    Identifier varchar(80), 
    ProductItemCode varchar(10), 
    SerialNumber varchar(48), 
    NetWeight decimal(13,2), 
    GrossWeight decimal(13,2), 
    PackDate datetime 'Attribute[@Name = "PackDate"]', 
    PlantID int 'Attribute[@Name = "PlantID"]', 
    SlgrDate datetime 'Attribute[@Name = "SlgrDate"]' 
    ) 
+0

工作了一種享受..非常感謝。真的很欣賞時間和精力。 – Harry

1

FROM OPENXML已經過時,不應該再使用(有極少數例外)

嘗試使用了最新 XML類型的方法:

SELECT p.value(N'@TUT',N'bit') AS TUT 
     ,p.value(N'@ID',N'nvarchar(max)') AS ID 
     ,p.value(N'(Identifier/text())[1]',N'nvarchar(max)') AS Identifier 
     ,p.value(N'(ProductItemCode/text())[1]',N'int') AS ProductItemCode 
     ,p.value(N'(Qty/text())[1]',N'int') AS Qty 
     ,p.value(N'(NetWeight/text())[1]',N'decimal(14,4)') AS NetWeight 
     ,p.value(N'(SerialNumber/text())[1]',N'int') AS SerialNumber 
     ,p.value(N'(ECertItemNumber/text())[1]',N'int') AS ECertItemNumber 
     ,p.value(N'(Markets/@Type)[1]',N'nvarchar(max)') AS Markets_Type 
     ,m.value(N'text()[1]',N'nvarchar(max)') AS Markets_Market 
     ,p.value(N'(Attribute[@Name="PackDate"]/text())[1]',N'datetime') AS PackDate 
     ,p.value(N'(Attribute[@Name="PlantID"]/text())[1]',N'int') AS PlantID 
     ,p.value(N'(Attribute[@Name="SlgrDate"]/text())[1]',N'datetime') AS SlgrDate 
FROM @xml.nodes(N'Transfer/Products/Product') AS A(p) 
CROSS APPLY a.p.nodes(N'Markets/Market') AS B(m); 

的結果

+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 
| TUT | ID     | Identifier   | ProductItemCode | Qty | NetWeight | SerialNumber | ECertItemNumber | Markets_Type | Markets_Market | PackDate    | PlantID | SlgrDate    | 
+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 
| 1 | 38319223176264031724 | 38319223176264031724 | 83192   | 1 | 23.1000 | 317   | 2    | ECERT  | EU    | 2016-09-20 00:00:00.000 | 124  | 2016-09-19 00:00:00.000 | 
+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 
| 1 | 38319223176264031724 | 38319223176264031724 | 83192   | 1 | 23.1000 | 317   | 2    | ECERT  | US    | 2016-09-20 00:00:00.000 | 124  | 2016-09-19 00:00:00.000 | 
+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 
| 1 | 28319219766306010024 | 28319219766306010024 | 83192   | 1 | 19.7000 | 100   | 2    | ECERT  | EU    | 2016-11-01 00:00:00.000 | 124  | 2016-10-31 00:00:00.000 | 
+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 
| 1 | 28319219766306010024 | 28319219766306010024 | 83192   | 1 | 19.7000 | 100   | 2    | ECERT  | US    | 2016-11-01 00:00:00.000 | 124  | 2016-10-31 00:00:00.000 | 
+-----+----------------------+----------------------+-----------------+-----+-----------+--------------+-----------------+--------------+----------------+-------------------------+---------+-------------------------+ 

提示:如果您不需要<Markets>作爲1:n-關係(這裏倍增結果集!),只需刪除CROSS APPLYm.value開始的行。

+0

謝謝你..我會給這個一個去...以及真正感謝時間和精力:) – Harry