2017-03-08 3 views
1

J'essaie d'extraire une valeur de mon XML et semble éprouver des difficultés. Espérons que quelqu'un peut aiderRécupère la valeur de l'attribut XML dans SQL Server 2008 à l'aide d'OPENXML

voici mon 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>' 

Ce que je veux extraire sont l'identifiant, ProductItemCode, Poids net, GrossWeight, et les valeurs d'attributs de PackDate et SlgrDate.

Je peux facilement obtenir tous les champs à l'exception des valeurs d'attribut de PackDate et SlgrDate

Voici mon code pour les champs

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 

le fichier xml contient le même que l'échantillon XML fourni Maintenant, je ne sais pas comment obtenir la valeur des attributs pour chaque produit.

Je courais ce dans SQL Server 2008

Répondre

1

Utilisez le ColPattern en option pour spécifier le XPath au nœud que vous voulez.

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

A travaillé un traitement .. merci beaucoup. vraiment apprécier le temps et les efforts. – Harry

1

FROM OPENXML est obsolète et ne doit pas être utilisé plus (sauf rares exceptions existent)

Essayez d'utiliser les XML de type-méthodes mise à jour:

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

Le résultat

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

Indice: Si vous n'avez pas besoin du <Markets> comme 1:n -relation (ici doublant votre resultset!), Il suffit de supprimer le CROSS APPLY et la ligne commençant par m.value.

+0

Merci .. je vais donner à celui-ci un coup aussi .. apprécie vraiment le temps et l'effort :) – Harry