从 sql 数据库中的 xml 列返回所有非标准节点(重复)的列表
Posted
技术标签:
【中文标题】从 sql 数据库中的 xml 列返回所有非标准节点(重复)的列表【英文标题】:Return list of all non standard nodes (duplicate) from xml column in sql database 【发布时间】:2022-01-03 02:47:45 【问题描述】:你能帮忙吗?
我有一个包含 NAME 和 XMLOUTPUT 列的表 'ED'
表格示例
Name XMLOUTPUT
Person1 Snippet below
XMLOUTPUT 是
<Fields>
<f Name="FIRSTNAME" ColumnOrder="0" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="KEYNAME" ColumnOrder="1" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="AGE" ColumnOrder="2" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="BIRTHDATE" ColumnOrder="3" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="LOOKUPID" ColumnOrder="4" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="MIDDLENAME" ColumnOrder="5" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Blue (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Red (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Yellow (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Green (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
</Fields>
我要做的是选择 ED 表中的名称列以及 XMLOUTPUT 中具有(颜色)的任何名称
理想的输出是
NAME XMLOUTPUT
Person1 Blue (color)
Person1 Red (color)
Person 1 Yellow (color)
Person1 Green (color)
到目前为止我最接近的是
select NAME as EDNAME,
CAST(REPLACE(REPLACE(CONVERT(nvarchar(max), XMLOUTPUT), '', ''), '', '')
AS xml).value('(//*:f/@Name) [1] ', 'varchar(50)')
as Color
from ED
where NAME = 'Person 1'
但是由于语句中的 [1],这确实检索但仅检索第一个。 我正在寻找可以提取所有值的东西,@Name like '%color%'
感谢收看。
【问题讨论】:
【参考方案1】:请尝试以下解决方案。
XPath XQuery contains()
函数非常适合您的场景。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [Name] VARCHAR(20), XMLOUTPUT XML);
INSERT INTO @tbl ([Name], XMLOUTPUT) VALUES
('Person1', N'<Fields>
<f Name="FIRSTNAME" ColumnOrder="0" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="KEYNAME" ColumnOrder="1" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="AGE" ColumnOrder="2" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="BIRTHDATE" ColumnOrder="3" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="LOOKUPID" ColumnOrder="4" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="MIDDLENAME" ColumnOrder="5" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Blue (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Red (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Yellow (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
<f Name="Green (color)" ColumnOrder="6" SortSequence="-1">
<FieldWasFlattened>false</FieldWasFlattened>
<ParentView/>
</f>
</Fields>');
-- DDL and sample data population, end
SELECT ID, [Name]
,c.value('@Name', 'VARCHAR(30)') AS Result
FROM @tbl
CROSS APPLY XMLOUTPUT.nodes('/Fields/f[contains(@Name, "(color)")]') AS t(c);
输出
+----+---------+----------------+
| ID | Name | Result |
+----+---------+----------------+
| 1 | Person1 | Blue (color) |
| 1 | Person1 | Red (color) |
| 1 | Person1 | Yellow (color) |
| 1 | Person1 | Green (color) |
+----+---------+----------------+
【讨论】:
非常感谢 Yitzhak,我无法使用包含标准的解决方案,如果我省略它,它会输出所有行....-我懒惰地把它卡在一个带有交换的选择中为 CROSS APPLY XMLOUTPUT.nodes('//*:f') AS t(c)) 输出你的交叉应用行 @davie,很高兴听到建议的解决方案对您有用。请不要忘记将其标记为答案。以上是关于从 sql 数据库中的 xml 列返回所有非标准节点(重复)的列表的主要内容,如果未能解决你的问题,请参考以下文章
MySQL从具有列名的select语句中的列列表中返回第一个非NULL值
在 SQL Server 中使用 value() 从 xml 列获取多条记录
在SQL Server中使用value()从xml列获取多个记录