给定一个包含如下所示数据的XML列,我想编写一个查询,其中XML中的每个ChangedColumn元素都有一条记录,每个子Name / OldValue / NewValue元素都有一列。
DECLARE @t XML = '
<ChangeEvent>
<ChangedColumn>
<Name>MyColumn</Name>
<OldValue>SomeOldValue</OldValue>
<NewValue>SomeNewValue</NewValue>
</ChangedColumn>
<ChangedColumn>
<Name>SomeOtherColumn</Name>
<OldValue>1</OldValue>
<NewValue>2</NewValue>
</ChangedColumn>
</ChangeEvent>
'
所以结果看起来像这样......
Name OldValue NewValue
MyColumn SomeOldValue SomeNewValue
SomeOtherColumn 1 2
下面的查询将在一列中为我提供所有数据,但我希望ChangedColumn元素的每个子节点的值位于不同的列中,最好是列名与元素名称匹配。
SELECT node.value('.', 'VARCHAR(MAX)')
FROM @t.nodes('/ChangeEvent/ChangedColumn') t(node)
我有什么想法可以修复此查询以提供我需要的结果吗?
答案 0 :(得分:1)
您可以在.value
方法中指定节点名称:
SELECT Name = node.value('Name[1]', 'VARCHAR(MAX)'),
OldValue = node.value('OldValue[1]', 'VARCHAR(MAX)'),
NewValue = node.value('NewValue[1]', 'VARCHAR(MAX)')
FROM @t.nodes('/ChangeEvent/ChangedColumn') t(node);
答案 1 :(得分:0)
GarethD的答案可能更好,但在我等待的时候,我确实找到了另一种方法,如下图所示......
SELECT
node.query('./Name') as Name,
node.query('./OldValue') as OldValue,
node.query('./NewValue') as NewValue
FROM @t.nodes('/ChangeEvent/ChangedColumn') t(node)
这包括带有值的XML标签,所以我绝对更喜欢GarethD的答案。但是,我发布了这个以防万一,如果他们需要看到不止一种方法来解决问题,这可以帮助其他人。
我不知道这种方式表现是否更糟,但我认为它可能会更糟。