SQL Server:递归动态 SQL 难题

Shi*_*iva 2 sql-server dynamic-sql

我正在看这篇关于trim all columns of a table 的帖子。在答案查询脚本中,列名被连接起来,没有任何循环操作。我简化了它以检查其工作流程,如下所述。

  • 创建一个新的数据库

  • 创建一个包含三列的新表,如下面的脚本所示。(不需要插入值)

    Create table table1(id int, name varchar(20), city varchar(20))
    
    Run Code Online (Sandbox Code Playgroud)

    在 T-SQL 脚本下面执行,结果xxx [id] [name] [city] 是单行。

    Declare @a as varchar(4000)
    SET @a = 'xxx '
    SELECT @a = @a + '['+COLUMN_NAME+'] ' FROM INFORMATION_SCHEMA.COLUMNS 
    SELECT @a
    
    Run Code Online (Sandbox Code Playgroud)

以下脚本导致 3 行

Declare @a as varchar(4000)
SET @a = 'xxx '
SELECT 'b' = @a + '['+COLUMN_NAME+'] ' FROM INFORMATION_SCHEMA.COLUMNS 
Run Code Online (Sandbox Code Playgroud)

为了更好地理解,我使用Top 1. 这结果xxx [id]

Declare @a as varchar(4000)
SET @a = 'xxx '
SELECT Top 1 @a = @a + '['+COLUMN_NAME+'] ' FROM INFORMATION_SCHEMA.COLUMNS 
SELECT @a
Run Code Online (Sandbox Code Playgroud)

我对 Top 2 查询感到困惑。这导致了xxx [id] [name]

正如我所期望的那样,xxx [id] xxx [id] [name]即第一个值 + 第二个值。我哪里错了。

我很想知道列名是如何连接的。抱歉,我无法为这个拼图设计更好的标题。

Mik*_*son 7

我很想知道列名是如何连接的。

实在回答不上来。SQL Server 的一些内部工作有时会产生这样的结果。

该技术已经存在了相当长的一段时间。Microsoft 不支持该功能并建议不要使用它。

来自SET @local_variable (Transact-SQL)

不要在 SELECT 语句中使用变量来连接值(即计算聚合值)。可能会出现意外的查询结果。这是因为 SELECT 列表中的所有表达式(包括赋值)不能保证对每个输出行只执行一次。

相反,您可以使用游标或for xml技巧来做同样的事情。

declare @a as varchar(4000);
set @a = 'xxx ';

set @a = @a + (
              select quotename(COLUMN_NAME) as '*'
              from INFORMATION_SCHEMA.COLUMNS
              for xml path(''), type
              ).value('text()[1]', 'varchar(4000)');
Run Code Online (Sandbox Code Playgroud)

结果: xxx [city][id][name]