使用值数组创建的动态 SQL

问题描述 投票:0回答:1

所以,这就是我所拥有的: 列名列表,例如(“名称”、“代码”、“标题”),可以是数组,但不一定是,它可以是任何内容。我只有一个列名称列表。

然后我必须创建一个稍后必须执行的动态sql select。动态 sql 选择正在生成 xml,因此它使用“for xml 路径”,并且非常复杂,因此我将尝试使其更简单:

@sql = select @column_name, some_fixed_column
       from t_table
       where some_Condition
       for xml path;

这必须是动态查询,加上它会创建 xml,所以它非常复杂,但我想让它以某种方式遍历列表中的所有列名称,所以一般结果会是这样的

select Name, some_fixed_column from tb_table where some_Condition for xml path;
select Code, some_fixed_column from tb_table where some_Condition for xml path;
select Title, some_fixed_column from tb_table where some_Condition for xml path;

我什至无法使用+或Union,因为它不适用于“for xml path”查询(我尝试过)。该查询相当复杂,并且它已经可以在多个 xml 级别上运行。 这可能吗?

sql arrays sql-server xml dynamic
1个回答
0
投票

在 SQL Server 2017 或更高版本中,一种方法是对列名集使用

STRING_AGG()

SQL Server 没有数组。模拟数组的一种方法就是使用逗号分隔的列表,然后用

STRING_SPLIT()
将它们分开,如下所示:

DECLARE @sql nvarchar(max), 
  
        @ColumnNames nvarchar(max) 
        = N'Name,Code,Title',
  
        @QueryTemplate nvarchar(max) 
        = N'SELECT %col%, fixed_column FROM whatever FOR XML PATH;';

SELECT @sql = STRING_AGG(REPLACE(@QueryTemplate, '%col%', value), 
       char(13) + char(10))     
  FROM STRING_SPLIT(@ColumnNames, ',');

PRINT @sql;
-- execute it using EXEC sys.sp_executesql @sql;

结果:

SELECT Name, fixed_column FROM whatever FOR XML PATH;
SELECT Code, fixed_column FROM whatever FOR XML PATH;
SELECT Title, fixed_column FROM whatever FOR XML PATH;

或者如果你有一套,那就更简单了:

DECLARE @Columns table(name sysname); -- or a TVP

INSERT @Columns(name) VALUES(N'Name'),(N'Code'),(N'Title');

DECLARE @sql nvarchar(max), 
  
        @QueryTemplate nvarchar(max) 
        = N'SELECT %col%, fixed_column FROM whatever FOR XML PATH;';

SELECT @sql = STRING_AGG(REPLACE(@QueryTemplate, '%col%', name), 
       char(13) + char(10))     
  FROM @Columns;

PRINT @sql;
-- execute it using EXEC sys.sp_executesql @sql;
© www.soinside.com 2019 - 2024. All rights reserved.