在每个子节点使用单独的列查询xml时遇到问题

时间:2014-05-20 16:14:50

标签: sql sql-server xml tsql xquery

给定一个包含如下所示数据的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)

我有什么想法可以修复此查询以提供我需要的结果吗?

2 个答案:

答案 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的答案。但是,我发布了这个以防万一,如果他们需要看到不止一种方法来解决问题,这可以帮助其他人。

我不知道这种方式表现是否更糟,但我认为它可能会更糟。