使用 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
.
开头的行
我正在尝试从我的 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
.