用于将XML分解为列的SQL脚本

时间:2016-07-16 14:21:09

标签: sql sql-server

我有一个以XML格式存储审计历史记录的表。每个文件都有自己的历史。如何解析每个文档的XML数据,XML中的每一列代表该列,以及该列中发生的实际列和操作。

示例:



"green"




UnsetChoice和Set Choice是列。 Name =代表行动。

2 个答案:

答案 0 :(得分:0)

可以使用XQueryOpenXml等功能解析Xml。

以下是xquery的一个示例:

declare @xml as xml = '<auditElement><field id="2881159" type="5" name="Responsiveness"' +
                  ' formatstring=""><unSetChoice>2881167</unSetChoice>' + 
                  '<setChoice>2881166</setChoice></field></auditElement>';

SELECT
  Nodes.node.value('(field/@id)[1]', 'INT') AS FieldId,
  Nodes.node.value('(field/@name)[1]', 'varchar(50)') AS FieldName,
  Nodes.node.value('(field/unSetChoice/text())[1]', 'INT') AS OldValue,
  Nodes.node.value('(field/setChoice/text())[1]', 'INT') AS NewValue
FROM
  @xml.nodes('//auditElement') AS Nodes(node);

结果:

FieldId     FieldName                                          OldValue    NewValue
----------- -------------------------------------------------- ----------- -----------
2881159     Responsiveness                                     2881167     2881166

答案 1 :(得分:0)

您可以使用OUTER APPLY,然后分解XML字段的各个部分。

value()方法需要XQuery个表达式。

例如:

DECLARE @T TABLE (Id int identity(1,1) primary key, XmlCol1 xml);

insert into @T (XmlCol1) values 
('<auditElement><field id="2881159" type="5" name="Responsiveness" formatstring=""><unSetChoice>2881167</unSetChoice><setChoice>2881166</setChoice></field></auditElement>'),
('<auditElement><field id="2881160" type="6" name="Responsiveness" ><unSetChoice>2881187</unSetChoice><setChoice>2881188</setChoice></field></auditElement>');

select * 
from ( 
  select
   Id,
   a.field.value('@id', 'int') as xmlid,
   a.field.value('(unSetChoice)[1]', 'int') as unSetChoice,
   a.field.value('(setChoice)[1]', 'int') as setChoice,
   a.field.value('@type', 'int') as type,
   a.field.value('@name', 'varchar(max)') as name,
   a.field.value('@formatstring', 'varchar(max)') as formatstring
  from @T t
  outer apply t.XmlCol1.nodes('/auditElement/field') as a(field)
  where a.field.value('@id', 'int') > 0 and Id > 0
) q 
where name = 'Responsiveness';

结果:

Id  xmlid   unSetChoice setChoice   type    name            formatstring
1   2881159 2881167     2881166     5       Responsiveness
2   2881160 2881187     2881188     6       Responsiveness  NULL