英文:
Parsing XML from a SQL Server table column into multiple rows
问题
SQL Server Standard 2017 on Windows Server 2019
我有一个 SQL Server 表,其中包含一个 XML 列,用于存储自定义数据
create table CustomerCrossReferences
(
customer BigInt,
product BigInt,
customColumns XML
)
customColumns
列包含以下格式的 XML 数据
insert into CustomerCrossReferences
values (69731, 157,
'<CustomColumnsCollection>
<CustomColumn>
<Name>MOI</Name>
<DataType>0</DataType>
<Value>10% max</Value>
</CustomColumn>
<CustomColumn>
<Name>PRO</Name>
<DataType>0</DataType>
<Value>26% min</Value>
</CustomColumn>
<CustomColumn>
<Name>FAT</Name>
<DataType>0</DataType>
<Value />
</CustomColumn>
<CustomColumn>
<Name>WAT</Name>
<DataType>0</DataType>
<Value />
</CustomColumn>
<CustomColumn>
<Name>FMT</Name>
<DataType>0</DataType>
<Value>None</Value>
</CustomColumn>
</CustomColumnsCollection>')
我需要使用这些数据在 SQL Server Report Writer 中构建报表数据集,选择与 Customer/Product 配对的 Name 对应的 Value。我不会在报表中使用 DataType。
目前,我考虑在报表结构中使用以下格式创建数据集
Customer Product Name DataType Value
-------------------------------------------------
69731 157 MOI 0 10% max
69731 157 PRO 0 26% min
69731 157 FAT 0
69731 157 WAT 0
69731 157 FMT 0
我可以使用以下方式创建这个数据集:
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[1]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[1]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[1]', 'varchar(max)')
from
CustomerCrossReferences
UNION ALL
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[2]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[2]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[2]', 'varchar(max)')
from
CustomerCrossReferences
UNION ALL
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[3]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[3]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[3]', 'varchar(max)')
from
CustomerCrossReferences
虽然这个方法有效,但对于我需要考虑的约20个 CustomColumn 数据元素来说可能会很繁琐。
我的问题是是否有更好的处理方法,无论是更简洁/高效的查询语句,还是能够直接在 Report Builder 中访问 XML 数据。谢谢。
英文:
SQL Server Standard 2017 on Windows Server 2019
I have a SQL Server table that contains an XML column to capture custom data
create table CustomerCrossReferences
(
customer BigInt,
product BigInt,
customColumns XML
)
The customColumns
column contains XML data in the following format
insert into CustomerCrossReferences
values (69731, 157,
'<CustomColumnsCollection>
<CustomColumn>
<Name>MOI</Name>
<DataType>0</DataType>
<Value>10% max</Value>
</CustomColumn>
<CustomColumn>
<Name>PRO</Name>
<DataType>0</DataType>
<Value>26% min</Value>
</CustomColumn>
<CustomColumn>
<Name>FAT</Name>
<DataType>0</DataType>
<Value />
</CustomColumn>
<CustomColumn>
<Name>WAT</Name>
<DataType>0</DataType>
<Value />
</CustomColumn>
<CustomColumn>
<Name>FMT</Name>
<DataType>0</DataType>
<Value>None</Value>
</CustomColumn>
</CustomColumnsCollection>')
I need to use this data to build a dataset in a report built in SQL Server Report Writer, selecting Value corresponding to the Name for the Customer/Product pairing. I won't be using DataType in the report.
At the moment I am thinking I should create a dataset in the following format to use in within my report structure
Customer Product Name DataType Value
-------------------------------------------------
69731 157 MOI 0 10% max
69731 157 PRO 0 26% min
69731 157 FAT 0
69731 157 WAT 0
69731 157 FMT 0
I can create this dataset with the following:
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[1]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[1]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[1]', 'varchar(max)')
from
CustomerCrossReferences
UNION ALL
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[2]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[2]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[2]', 'varchar(max)')
from
CustomerCrossReferences
UNION ALL
select
customer
,product
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Name)[3]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/DataType)[3]', 'varchar(max)')
,customColumns.value('(/CustomColumnsCollection/CustomColumn/Value)[3]', 'varchar(max)')
from
CustomerCrossReferences
While this works it will be cumbersome as I have approx 20 CustomColumn
data elements to consider.
My question is whether there is a better way of handling this, either as a more concise/efficient query statement, or by being able to directly address the XML data within Report Builder. Thanks
答案1
得分: 3
你可以使用XQuery的nodes()
方法以行格式获取你的XML数据,类似以下方式:
SELECT cc.customer, cc.product
, n.value('(Name/text())[1]', 'nvarchar(100)') AS Name
, n.value('(DataType/text())[1]', 'int') AS DataType
, n.value('(Value/text())[1]', 'nvarchar(100)') AS Value
FROM CustomerCrossReferences cc
CROSS APPLY customColumns.nodes('/CustomColumnsCollection/CustomColumn') n(n)
结合value()
方法,你可以检索CustomColumn的各个元素。
英文:
You can use XQuery nodes()
method to get your xml data in row format. something like:
SELECT cc.customer, cc.product
, n.value('(Name/text())[1]', 'nvarchar(100)') AS Name
, n.value('(DataType/text())[1]', 'int') AS DataType
, n.value('(Value/text())[1]', 'nvarchar(100)') AS Value
FROM CustomerCrossReferences cc
CROSS APPLY customColumns.nodes('/CustomColumnsCollection/CustomColumn') n(n)
Combined with value()
method, you can retrieve individual elements of CustomColumn.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论