从 SQL Server 中的 XML 数据类型字段中提取数据
Posted
技术标签:
【中文标题】从 SQL Server 中的 XML 数据类型字段中提取数据【英文标题】:Extract data from XML data type field in SQL Server 【发布时间】:2020-04-16 16:24:34 【问题描述】:我在 ReportServer 数据库上执行以下查询。
SELECT ItemID, CAST(CAST(Content AS VARBINARY(MAX)) AS XML) Content
FROM dbo.Catalog
WHERE Type = 8
我想提取Content
列的字段列表。 content
列是 XML
数据类型并包含如下 XML:
<SharedDataSet xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSet Name="DataSet1">
<Query>
<DataSourceReference>DDSDB</DataSourceReference>
<CommandText>SELECT z.AccessoryPercent
,CASE
WHEN z.AccessoryPercent>0.20 Then 1
WHEN z.AccessoryPercent >=0.10 THEN 0
ELSE -1
end AS AccessoryState
FROM (
SELECT (a.FixedPrice - a.NetSalesPrice)/a.FixedPrice AS AccessoryPercent
FROM acc.Fact_Crm_Accessory a
)z</CommandText>
</Query>
<Fields>
<Field Name="AccessoryPercent">
<DataField>AccessoryPercent</DataField>
<rd:TypeName>System.Decimal</rd:TypeName>
</Field>
<Field Name="AccessoryState">
<DataField>AccessoryState</DataField>
<rd:TypeName>System.Int32</rd:TypeName>
</Field>
</Fields>
</DataSet>
</SharedDataSet>
我的预期结果是:
DataSetName Field
-------------------------------------
DataSet1 AccessoryPercent
DataSet1 AccesspryState
提前致谢
编辑:我编写了以下查询以便于查询。
CREATE TABLE #t (data XML)
INSERT INTO #t
VALUES('<SharedDataSet xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSet Name="DataSet1">
<Query>
<DataSourceReference>DDSDB</DataSourceReference>
<CommandText>SELECT z.AccessoryPercent
,CASE
WHEN z.AccessoryPercent>0.20 Then 1
WHEN z.AccessoryPercent >=0.10 THEN 0
ELSE -1
end AS AccessoryState
FROM (
SELECT (a.FixedPrice - a.NetSalesPrice)/a.FixedPrice AS AccessoryPercent
FROM acc.Fact_Crm_Accessory a
)z</CommandText>
</Query>
<Fields>
<Field Name="AccessoryPercent">
<DataField>AccessoryPercent</DataField>
<TypeName>System.Decimal</TypeName>
</Field>
<Field Name="AccessoryState">
<DataField>AccessoryState</DataField>
<TypeName>System.Int32</TypeName>
</Field>
</Fields>
</DataSet>
</SharedDataSet>')
SELECT *
FROM #t AS t
【问题讨论】:
【参考方案1】:(1) 我们需要考虑默认命名空间。
(2) 第二个CROSS APPLY
处理数据集与其字段之间的一对多关系。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (xmldata XML);
INSERT INTO @tbl
VALUES('<SharedDataSet xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSet Name="DataSet1">
<Query>
<DataSourceReference>DDSDB</DataSourceReference>
<CommandText>SELECT z.AccessoryPercent
,CASE
WHEN z.AccessoryPercent>0.20 Then 1
WHEN z.AccessoryPercent >=0.10 THEN 0
ELSE -1
end AS AccessoryState
FROM (
SELECT (a.FixedPrice - a.NetSalesPrice)/a.FixedPrice AS AccessoryPercent
FROM acc.Fact_Crm_Accessory a
)z</CommandText>
</Query>
<Fields>
<Field Name="AccessoryPercent">
<DataField>AccessoryPercent</DataField>
<TypeName>System.Decimal</TypeName>
</Field>
<Field Name="AccessoryState">
<DataField>AccessoryState</DataField>
<TypeName>System.Int32</TypeName>
</Field>
</Fields>
</DataSet>
</SharedDataSet>');
-- DDL and sample data population, end
;WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition')
SELECT c.value('@Name','VARCHAR(30)') AS DataSetName
, f.value('@Name','VARCHAR(30)') AS Field
FROM @tbl AS tbl
CROSS APPLY tbl.xmldata.nodes('/SharedDataSet/DataSet') AS t(c)
CROSS APPLY t.c.nodes('Fields/Field') AS f(f);
输出
+-------------+------------------+
| DataSetName | Field |
+-------------+------------------+
| DataSet1 | AccessoryPercent |
| DataSet1 | AccessoryState |
+-------------+------------------+
【讨论】:
以上是关于从 SQL Server 中的 XML 数据类型字段中提取数据的主要内容,如果未能解决你的问题,请参考以下文章
动态获取 SQL Server 中不同列中的 XML 数据类型值
Spring JDBC for SQL Server - 使用 SQLXML 数据类型产生 SQLServerException:不允许从数据类型 xml 到 nvarchar(max) 的隐式转换