SQL Server获取全表最大插入日期:无ins_date表报错解决方案
解决SQL Server遍历表获取最大ins_date时的报错问题
这问题我之前帮同事处理过,确实直接用sp_MSforeachtable遍历所有表的话,碰到没有ins_date列的表就会触发语法错误。给你两个实用的解决方案,按需选就行:
方案一:只遍历包含ins_date列的表(高效推荐)
这个方案先通过系统视图筛选出所有带有ins_date列的表,再针对性遍历,从根源上避免报错。
你可以直接用sp_MSforeachtable的@whereand参数来过滤表:
EXEC sp_MSforeachtable @command1 = 'SELECT ''?'' AS TableName, MAX(ins_date) AS LastInsertDate FROM ?', @whereand = 'AND EXISTS (SELECT 1 FROM sys.columns c WHERE c.object_id = o.id AND c.name = ''ins_date'')'
- 这里的
o是sp_MSforeachtable内置的表对象别名,代表当前遍历到的表 - 只会对存在
ins_date列的表执行查询,完全不会触发报错
如果想先确认筛选出的表列表,可以先执行这条查询查看:
SELECT QUOTENAME(s.name) + '.' + QUOTENAME(t.name) AS TableName FROM sys.tables t JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE EXISTS ( SELECT 1 FROM sys.columns c WHERE c.object_id = t.object_id AND c.name = 'ins_date' )
方案二:遍历所有表,无ins_date列时返回提示(保留全表信息)
如果你需要看到所有表的状态(包括没有ins_date列的表),可以在动态SQL里加判断逻辑,遇到无列的表就返回标记值,而不是报错:
EXEC sp_MSforeachtable @command1 = ' DECLARE @tableName NVARCHAR(128) = ''?'' IF EXISTS (SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(@tableName) AND c.name = ''ins_date'') BEGIN SELECT @tableName AS TableName, MAX(ins_date) AS LastInsertDate FROM ? END ELSE BEGIN SELECT @tableName AS TableName, ''无ins_date列'' AS LastInsertDate END'
这个方法会遍历所有表,有列的返回最大插入日期,没列的返回自定义提示,全程不会报错。
小提示
- 注意用
QUOTENAME处理表名(sp_MSforeachtable自动帮你做了,所以上面的例子里?会被转成带方括号的合法表名),避免表名含特殊字符或关键字时触发语法错误 - 如果你的
ins_date列可能有NULL值,MAX()会自动忽略NULL,不影响结果
内容的提问来源于stack exchange,提问作者Pablo M
相关产品推荐
相关产品推荐

