如何查找存储过程依赖的同服务器其他数据库中的所有表
如何找出存储过程依赖的同服务器其他数据库中的表
问题原因
你原本使用的sys.sql_dependencies是已被弃用的系统视图,它仅能追踪当前数据库内的对象依赖关系,无法识别跨库引用的表。
解决方案:使用sys.sql_expression_dependencies
SQL Server提供的sys.sql_expression_dependencies视图可以完整记录存储过程的静态引用,包括跨库、甚至跨服务器的对象。以下是改进后的查询语句:
SELECT DISTINCT p.name AS proc_name, -- 跨库引用时显示对应数据库名,当前库则显示当前数据库名称 COALESCE(d.referenced_database_name, DB_NAME()) AS referenced_database, COALESCE(d.referenced_schema_name, 'dbo') AS referenced_schema, d.referenced_entity_name AS table_name, -- 可选:验证引用对象是否为表 CASE WHEN OBJECT_ID( QUOTENAME(COALESCE(d.referenced_database_name, DB_NAME())) + '.' + QUOTENAME(COALESCE(d.referenced_schema_name, 'dbo')) + '.' + QUOTENAME(d.referenced_entity_name) ) IS NOT NULL AND OBJECTPROPERTY( OBJECT_ID( QUOTENAME(COALESCE(d.referenced_database_name, DB_NAME())) + '.' + QUOTENAME(COALESCE(d.referenced_schema_name, 'dbo')) + '.' + QUOTENAME(d.referenced_entity_name) ), 'IsTable' ) = 1 THEN '是表' ELSE '非表对象' END AS is_table FROM sys.procedures p INNER JOIN sys.sql_expression_dependencies d ON p.object_id = d.referencing_id WHERE p.name LIKE '%sp_example%' AND d.referenced_class_desc = 'OBJECT_OR_COLUMN' -- 仅筛选对象/列级引用 ORDER BY proc_name, referenced_database, referenced_schema, table_name
语句说明
referenced_database_name:存储跨库引用的数据库名称,当前库引用时该字段为NULL,用COALESCE替换为当前库名。referenced_schema_name:表所在的架构,默认填充为dbo。- 可选的
CASE语句:通过OBJECT_ID和OBJECTPROPERTY验证引用的对象是否为表,避免混入视图、存储过程等其他对象。
处理动态SQL引用的情况
如果存储过程中使用动态SQL生成跨库表引用(比如用字符串拼接表名),sys.sql_expression_dependencies无法解析这种动态引用。此时可以查询存储过程的定义文本,手动提取相关表名:
SELECT p.name AS proc_name, m.definition AS proc_definition FROM sys.procedures p INNER JOIN sys.sql_modules m ON p.object_id = m.object_id WHERE p.name LIKE '%sp_example%' AND m.definition LIKE '%.[%].[%]' -- 匹配「数据库名.架构名.表名」格式的引用
这种方法需要你手动分析定义文本,或编写正则表达式提取表名,但可能会误匹配注释中的内容,仅作为静态分析的补充。
注意事项
- 执行查询的账号需要具备访问目标数据库
sys.objects视图的权限,否则OBJECT_ID会返回NULL。 sys.sql_expression_dependencies仅能捕获静态编译的引用,动态生成的引用无法自动识别。
内容的提问来源于stack exchange,提问作者adam
相关产品推荐
相关产品推荐

