从结构未知的XML中选择

时间:2013-03-18 16:24:47

标签: sql sql-server xml

我在SQL Server 2008中有一个表,其结构如下:

id     = int
numero = int
datos  = xml
[other_misc_fields]

您可以在此sql fiddle上看到包含一些示例数据的表格。正如您在链接上看到的,字段 datos (数据)是一个XML。此XML没有已知的结构。我所知道的是,根是“lote”,并且每个字段都有一个属性“title”,它是该字段的“显示名称”。我希望能够沿着这一行查询一些内容

id | numero | display_name_field_1 | display_name_field_2 | display_name_field_3
 1 |   23   |     value_field_1    |     value_field_2    |     value_field_3

使用一些dynamic sql(来自another so answer)我可以从每个节点获取值,但我无法弄清楚如何使用title属性重命名它:

select @SQL = 'select '+stuff(
  (
  select ',T.N.value('''+T.N.value('local-name(.)', 'sysname')+'[1]'', ''varchar(max)'') as '+T.N.value('local-name(.)', 'sysname')
  from @XML.nodes('/*[local-name(.)=sql:variable("@KnownName")]/*') as T(N)
  for xml path(''), type
  ).value('.', 'nvarchar(max)'), 1, 1, '')+
  ' from @XML.nodes(''/*[local-name(.)=sql:variable("@KnownName")]'') as T(N)

@KnownName是“lote”。

如何修改该查询,以便该字段重命名为该节点的 @title 属性?或者,有没有比动态sql更好的方法呢?

1 个答案:

答案 0 :(得分:0)

事实证明这相对容易。唯一的问题是列名称不能轻易设置为动态值。最后,我决定处理XML客户端,但这是一种类似于我想要的方式,以防任何人感兴趣:

SELECT @SQL = 'select '+stuff(
      (
      SELECT ',T.N.value('''+T.N.value('local-name(.)', 'sysname')+'[1]'',''varchar(max)'') as '+ T.N.value('local-name(.)', 'sysname')+',  T.N.value(''('+T.N.value('local-name(.)', 'sysname')+'/@title)[1]'+''',''varchar(max)'') as '+ T.N.value('local-name(.)', 'sysname')+'@title'
      FROM @XML.nodes('/*[local-name(.)=sql:variable("@KnownName")]/*') AS T(N)
      FOR xml path(''), TYPE
      ).value('.', 'nvarchar(max)'), 1, 1, '')+
      ' from @XML.nodes(''/*[local-name(.)=sql:variable("@KnownName")]'') as T(N)'

您可以在此sqlfiddle中看到它“在行动中”:http://www.sqlfiddle.com/#!3/5408e/13/0