SQL动态遍历表名时如何添加通配符以匹配新增表?
解决动态匹配带年份/年月后缀的表名问题
没问题,我帮你搞定这个需求!你的原有代码只能匹配hail-YYYY格式的表,现在新增了hail-YYYYMM的表,我们需要调整逻辑,让动态SQL能自动匹配所有以目标年份开头的表,不管后面有没有月份后缀。
方案一:用系统视图自动获取匹配表(推荐,SQL Server 2017+)
这个方法会直接从数据库的系统表中查询所有符合条件的表名,自动拼接查询语句,兼容性更强:
DECLARE @Year_Id INT = 2001; DECLARE @SQLQUERY NVARCHAR(MAX); WHILE @Year_Id <= 2018 BEGIN -- 拼接所有匹配当前年份的表查询语句 SELECT @SQLQUERY = STRING_AGG( 'SELECT CELL_ID, LAT, LON, SEVPROB, PROB, MAXSIZE, _ZTIME FROM [SWDI].[dbo].[' + name + ']', ' UNION ALL ' ) FROM sys.tables WHERE name LIKE 'hail-' + CONVERT(VARCHAR(4), @Year_Id) + '%' -- 匹配hail-YYYY或hail-YYYYMM AND SCHEMA_NAME(schema_id) = 'dbo' AND OBJECT_ID('[SWDI].[dbo].[' + name + ']') IS NOT NULL; -- 如果找到匹配的表,执行动态SQL IF @SQLQUERY IS NOT NULL BEGIN EXEC sp_executesql @SQLQUERY; END SET @Year_Id = @Year_Id + 1; END
方案二:兼容SQL Server 2016及更早版本
如果你的SQL Server版本不支持STRING_AGG,可以用FOR XML PATH来拼接查询语句:
DECLARE @Year_Id INT = 2001; DECLARE @SQLQUERY NVARCHAR(MAX); WHILE @Year_Id <= 2018 BEGIN SET @SQLQUERY = ''; -- 逐个拼接匹配表的查询 SELECT @SQLQUERY = @SQLQUERY + 'SELECT CELL_ID, LAT, LON, SEVPROB, PROB, MAXSIZE, _ZTIME FROM [SWDI].[dbo].[' + name + '] UNION ALL ' FROM sys.tables WHERE name LIKE 'hail-' + CONVERT(VARCHAR(4), @Year_Id) + '%' AND SCHEMA_NAME(schema_id) = 'dbo' AND OBJECT_ID('[SWDI].[dbo].[' + name + ']') IS NOT NULL; -- 去掉最后多余的"UNION ALL"并执行 IF LEN(@SQLQUERY) > 0 BEGIN SET @SQLQUERY = LEFT(@SQLQUERY, LEN(@SQLQUERY) - 10); EXEC sp_executesql @SQLQUERY; END SET @Year_Id = @Year_Id + 1; END
注意事项
- 确保所有匹配的表结构完全一致(列名、数据类型相同),否则
UNION ALL会报错; - 这个方法避免了硬编码表名,后续新增
hail-YYYYMM或其他同前缀的表都会被自动匹配,不用修改代码; - 从系统视图获取表名的方式相对安全,能降低SQL注入风险。
内容的提问来源于stack exchange,提问作者Jatin Garg
相关产品推荐
相关产品推荐

