我有两张桌子:
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中提取的标记名称?
我希望我的解释足够好:)。
谢谢!
答案 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