使用 OPENXML 从 SQL Server 2008 中的 XML 属性获取值

Get Value from XML attribute in SQL Server 2008 Using OPENXML

我正在尝试从我的 XML 中提取一个值,但似乎很困难。希望有人能帮忙

这是我的 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>'

我要提取的是 Identifier、ProductItemCode、NetWeight、GrossWeight 以及 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 提供的样本相同的内容 现在我不知道如何从每个产品的属性中获取值。

我是运行这个在SQLSERVER 2008

使用可选的 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"]'
    ) 

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 APPLY 和以 m.value.

开头的行