如何筛选SQL Server中包含存储过程的数据库名称
找出SQL Server中包含存储过程的数据库
嘿,我完全懂你的需求——面对97个数据库,只想快速筛选出那些带有存储过程的,不用一个个去查对吧?你提到的两个查询思路是对的,只是需要把它们用合适的方式串联起来,而且咱们可以用SQL Server更现代、更可靠的系统视图来实现,比sysobjects更精准。
方法一:用动态SQL遍历所有数据库(推荐)
这个方法会逐个检查每个在线数据库,只要里面存在存储过程就输出它的名称,逻辑清晰且结果准确:
DECLARE @SQL NVARCHAR(MAX) = N''; -- 遍历所有在线数据库,拼接检查语句 SELECT @SQL += N' IF EXISTS (SELECT 1 FROM [' + QUOTENAME(name) + N'].sys.procedures) SELECT ''' + name + N''' AS DatabaseWithProcedures;' FROM sys.databases WHERE state = 0; -- 只检查处于在线状态的数据库 -- 执行拼接好的SQL语句 EXEC sp_executesql @SQL;
代码说明:
QUOTENAME(name):用来处理那些名称包含特殊字符(比如空格、连字符)的数据库,避免SQL语法错误。sys.procedures:这是SQL Server 2005及以后版本官方推荐的系统视图,专门用来存储存储过程的信息,比旧的sysobjects更精准,不会误判其他类型的对象。state = 0:过滤掉离线、还原中的数据库,只检查正常可用的库。
方法二:通过系统视图关联查询
如果你偏好更简洁的写法,也可以用跨库系统视图关联的方式,不过需要确保你有足够的权限访问所有数据库的系统对象:
SELECT DISTINCT d.name AS DatabaseWithProcedures FROM sys.databases d WHERE EXISTS ( SELECT 1 FROM sys.procedures p WHERE p.database_id = d.database_id ) AND d.state = 0;
注意事项
- 权限问题:执行这些查询需要你拥有
VIEW ANY DEFINITION服务器权限,或者每个目标数据库的VIEW DEFINITION权限,否则可能会返回不完整的结果。 - 避免用sysobjects:虽然你提到了
sysobjects,但它是为了兼容旧版本保留的视图,现在更推荐用sys.procedures,因为它只针对存储过程,不会把触发器、函数等其他对象误判进来。
内容的提问来源于stack exchange,提问作者Luiz Felippe Serrano




