从动态指定的数据字段的XML标记中获取值

时间:2014-10-09 21:00:59

标签: sql sql-server xml tsql select

我有两张桌子:

Table1有一个我想从XML字段中提取的XML标记名称列表。我通过运行此查询来模拟这个

SELECT 'CLIENT' UNION SELECT 'FEE' UNION SELECT 'ADDRESS'

这会产生一个包含3行的列,其名称将用于从XML标记中提取相应的数据。

第二个表有一个名为ClientData的列,它是XML格式,有数千行数据。我的任务是从Table1中指定的XML标记中提取值,在这种情况下,我想要3 xml标记的值:Client,FEE和ADDRESS。

所以,如果XML是这个

<XML>
    <CLIENT>some client</CLIENT>
    <FEE>some fee</FEE>
    <ADDRESS>some address</ADDRESS>
 </XML>

运行查询后我应该得到这个:

Client, FEE, ADDRESS

some client, some fee, some address

现在我有一个问题:

SELECT coalesce(Cast(ClientData as xml).value('(/XML/CLIENT)[1]', 'varchar(max)'), ''), coalesce(Cast(ClientData as xml).value('(/XML/FEE)[1]', 'varchar(max)'), ''), coalesce(Cast(ClientData as xml).value('(/XML/ADDRESS)[1]', 'varchar(max)'), '') FROM dbo.Table2 WITH(NOLOCK)

这给了我必要的结果,但它不是动态的。这意味着,如果我想要包含第4个xml值,让我们说PHONE,我需要将coalesce(Cast(ClientData as xml).value('(/XML/PHONE)[1]', 'varchar(max)'), '')添加到SELECT

我的问题是, 如何使我的查询动态化,以便我不使用Tabl1作为标记名称来源提取而不是硬编码我想从表2中的XML中提取的标记名称?

我希望我的解释足够好:)。

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用DYNAMIC SQL

来实现此目的

TagsTable应该包含所有可能的标签

然后我们可以使用标签名称构建SQL并执行它

create table TagsTable
(  tagName varchar(256)
)

insert into TagsTable values ('CLIENT')
insert into TagsTable values ('FEE')
insert into TagsTable values ('ADDRESS')

declare @query nvarchar(max)

SELECT @query = STUFF((select  ',' + 'coalesce(Cast(ClientData as xml).value(''(/XML/' 
                                   + tagName + ')[1]'', ''varchar(max)''), '''') as ' + tagName +' '
FROM TagsTable
FOR XML PATH ('') ), 1,1,'')


SET @query = 'SELECT ' +  @query + 'FROM dbo.Table2 WITH(NOLOCK)'
select @query

exec sp_executesql @query