SQL Server查询的SELECT列列表中能否使用子查询动态获取表全列?
问题原因
你现有的写法无法生效的核心原因是:SQL的查询列、表名等结构属于元数据,需要在语句执行前完成静态编译,你在SELECT子句中嵌套查询COLUMN_NAME的逻辑,返回的是列名的字符串值,不会被引擎识别为要查询的实际字段,自然得不到预期结果。
正确实现方式
SQL Server中需要通过动态SQL实现列列表动态生成的需求,步骤如下:
-- 声明变量存储拼接后的列列表 DECLARE @column_list NVARCHAR(MAX) -- 从系统视图查询所有列,用逗号拼接,QUOTENAME用于处理含特殊字符/关键字的列名 SELECT @column_list = STRING_AGG(QUOTENAME(COLUMN_NAME), N', ') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_CATALOG = N'table_catalog' -- 替换为你的库名 AND TABLE_SCHEMA = N'table_schema' -- 替换为你的架构名 AND TABLE_NAME = N'table_name' -- 替换为你的表名 -- 拼接最终要执行的SQL语句 DECLARE @exec_sql NVARCHAR(MAX) = N'SELECT DISTINCT ' + @column_list + N' FROM [table_catalog].[table_schema].[table_name]' -- 执行动态SQL EXEC sp_executesql @exec_sql
低版本兼容方案
如果你使用的是SQL Server 2016及更早版本,不支持STRING_AGG函数,可用以下逻辑替换列拼接部分:
DECLARE @column_list NVARCHAR(MAX) SELECT @column_list = COALESCE(@column_list + N', ', N'') + QUOTENAME(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_CATALOG = N'table_catalog' AND TABLE_SCHEMA = N'table_schema' AND TABLE_NAME = N'table_name'
注意事项
- 建议在查询系统视图时同时过滤库名、架构名,避免多个库/架构下存在同名表,导致取到错误的列列表
QUOTENAME函数不可省略,避免列名含空格、特殊符号或是SQL关键字时执行报错- 执行动态SQL的账号需要同时拥有系统视图和目标表的访问权限
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

