SQL Server如何通过变量传入表名实现分年表批量查询
实现方案
先说明两个核心前提:你原写法无法运行的核心原因是T-SQL中表名属于编译期就要确定的对象标识符,不能直接在语句里用字符串拼接变量替换;你提到的CASE语句也无法实现这个需求——CASE是值表达式,只能返回数据值,不能返回表名、列名这类对象标识,这类动态表名场景必须通过动态SQL实现。
基础单表查询写法
你原有代码有两个基础语法错误:变量赋值时漏写了@前缀、INT类型变量赋值不需要加字符串单引号,修正后的单年份查询写法如下:
DECLARE @yr INT = 2022; DECLARE @exec_sql NVARCHAR(MAX); -- 显式把INT类型年份转为字符串拼接表名 SET @exec_sql = N'SELECT TOP 10 * FROM dbo.enc_TN_' + CAST(@yr AS NVARCHAR(4)) + N';'; -- 执行拼接好的动态语句 EXEC sp_executesql @exec_sql;
循环批量查询精简写法
不用重复写5组赋值+查询逻辑,用WHILE循环即可批量完成2018-2022年的表查询,分两种常见场景:
场景1:每个年份表返回独立结果集
和你原逻辑一致,执行后会返回5个独立的查询结果:
DECLARE @cur_yr INT = 2022; -- 从最新年份开始查询,和你原顺序匹配 DECLARE @min_yr INT = 2018; DECLARE @exec_sql NVARCHAR(MAX); WHILE @cur_yr >= @min_yr BEGIN SET @exec_sql = N'SELECT TOP 10 * FROM dbo.enc_TN_' + CAST(@cur_yr AS NVARCHAR(4)) + N';'; EXEC sp_executesql @exec_sql; SET @cur_yr = @cur_yr - 1; -- 年份递减进入下一轮 END
场景2:所有年份结果合并为单个结果集
如果需要把5个表的查询结果合并到同一张表返回,可以借助临时表存储:
-- 临时表字段请和你实际的enc_TN_年份表字段保持一致 CREATE TABLE #tmp_enc_data ( enc_id INT, enc_date DATE, patient_code NVARCHAR(64) -- 按实际表结构补全其余字段 ); DECLARE @cur_yr INT = 2022; DECLARE @min_yr INT = 2018; DECLARE @exec_sql NVARCHAR(MAX); WHILE @cur_yr >= @min_yr BEGIN SET @exec_sql = N' INSERT INTO #tmp_enc_data SELECT TOP 10 * FROM dbo.enc_TN_' + CAST(@cur_yr AS NVARCHAR(4)) + N'; '; EXEC sp_executesql @exec_sql; SET @cur_yr = @cur_yr - 1; END -- 统一返回合并后的结果 SELECT * FROM #tmp_enc_data; DROP TABLE #tmp_enc_data;
长期优化建议
如果这类按年分表的查询是高频需求,完全可以不用写动态SQL,直接创建分表联合视图即可,后续查询直接加年份过滤条件,写法更简单:
-- 创建跨所有年份表的视图 CREATE VIEW dbo.vw_all_enc_TN AS SELECT *, 2018 AS data_year FROM dbo.enc_TN_2018 UNION ALL SELECT *, 2019 AS data_year FROM dbo.enc_TN_2019 UNION ALL SELECT *, 2020 AS data_year FROM dbo.enc_TN_2020 UNION ALL SELECT *, 2021 AS data_year FROM dbo.enc_TN_2021 UNION ALL SELECT *, 2022 AS data_year FROM dbo.enc_TN_2022;
后续查对应年份数据直接写静态语句即可,不需要任何拼接:
SELECT TOP 10 * FROM dbo.vw_all_enc_TN WHERE data_year = 2022;
注意事项
- 拼接动态SQL时必须显式转换变量类型:INT类型的年份不能直接和字符串拼接,否则会报类型不匹配错误。
- 如果年份参数来自外部用户输入,必须做范围校验(比如限制值在2000到当前年份之间),避免SQL注入风险。
内容的提问来源于stack exchange,提问作者Drcline87
相关产品推荐
相关产品推荐

