繁体   English   中英

如何将多个 SQL“SELECT AS XML PATH”查询结果连接到一个 XML 文件中

[英]How to concatenate multiple SQL "SELECT AS XML PATH " query results INTO one XML file

我在一个 MS SQL 程序中有多个 SELECT... AS XML PATH 查询,但我需要程序的结果在一个 xml 文件中。

例如,如何在一个 SQL 程序中将多个 select... as xml 的结果 xml 连接成一个结果 xml 文件? 问题是,这些查询中的每一个都是使用 CURSOR 创建的,所以我不能使用 UNION ALL。

这个 cursor 从 INFORMATION_SCHEMA.TABLES 中获取表名,每个 select 来自不同的表。 不要复杂化,但每个 select 都是动态创建的,因为它首先创建为 VARCHAR,然后使用 exec(@sql) 执行,所以

fetch c_table_name from cursor_c
@sql=     ' select
           id as ''value/@id'',
           name as ''value''
           from _TABLENAME_
           where somevalue=cursorValue
           for xml path('''')'


set @sql = replace(sql, '_TABLENAME_, c_table_name
exec(@sql)

每个这样的 select xml 结果例如:

   <value id=1>aaaa</value>
   <value id=2>bbb</value>

cursor 中的下一个表可能会给出另一个结果,例如:

   <value id=11>ccc</value>
   <value id=21>ddd</value>

但结果将是单独的 xml 个文件,我只想要一个这样的文件:

<value id=1>aaaa</value>
<value id=2>bbb</value>
<value id=11>ccc</value>
<value id=21>ddd</value>
....

那可能吗? 我尝试将结果放入 xml 变量,然后将另一个结果添加到同一个变量,这不起作用。 我没有尝试过。 问题是每个 select 都依赖于 cursor。它必须是这样的,选择不是这么简单这只是例子。 甚至有可能有多个 SELECT... FOR XML PATH 语句,并通过将它们全部连接起来以某种方式管理它们以生成一个 XML 结果吗?

您可以使用STRING_AGG()构建一个 SQL 语句来创建您的联合,然后执行它,而不是使用 cursor 并一条一条地执行您的语句:

DECLARE @sql NVARCHAR(MAX) = '';
SELECT  @sql = STRING_AGG(CONCAT('SELECT id AS [value/@id], name AS [value] FROM ', 
                            QUOTENAME(TABLE_SCHEMA), '.', QUOTENAME(TABLE_NAME), 
                            ' FOR XML PATH('''')'), ' UNION ALL ')
FROM    INFORMATION_SCHEMA.TABLES 
WHERE   ....

PRINT @sql;
--EXECUTE sp_executesql @sql  -- Check first with print, then uncomment to execute

话虽如此,如果您有如此多的表,这些表之间的关系密切到足以联合在一起,但数量又多到需要动态 SQL 来引用它们,那么这对我来说有点代码味。 如果所有的表确实相关并且合并有意义,那么也许视图是有序的,或者它们实际上应该是一个表?


附录

如果您使用的是 2017 年之前的 SQL 服务器版本,那么您可以使用旧的 XML hack 将您的行连接成一个字符串:

DECLARE @sql NVARCHAR(MAX) = '';
SET @sql = STUFF((SELECT CONCAT(' UNION ALL SELECT id AS [value/@id], name AS [value] FROM ', 
                            QUOTENAME(TABLE_SCHEMA), '.', QUOTENAME(TABLE_NAME), 
                            ' FOR XML PATH('''')')
                FROM    INFORMATION_SCHEMA.TABLES 
                WHERE   .....
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 10, '')

也许您可以在 cursor 之前创建一个临时表,在 cursor 内部将每个 select 插入到该表中,并在 cursor 关闭后从该表中执行一个 select 然后删除它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM