应直接查询 sys.sql_expression_dependencies 视图获取存储过程的显式静态依赖,因其准确记录硬编码的表/视图引用;而 sys.dm_exec_describe_first_result_set 仅推测首个结果集结构,无法识别 dml 目标或动态 sql 引用。

直接查 sys.sql_expression_dependencies,别用 sys.dm_exec_describe_first_result_set —— 后者只猜返回结构,不反映真实引用。
查存储过程读写哪些表/视图:用 sys.sql_expression_dependencies
这个视图记录的是创建时解析出的显式静态依赖,比如 SELECT * FROM dbo.Orders 或 UPDATE Sales.vOrderSummary SET ... 这类硬编码引用。
- 动态 SQL(如
EXEC('SELECT * FROM ' + @tbl))完全不会出现 - 临时表(
#tmp)、表变量(@t TABLE(...))也不会被记录 - 跨库引用必须写三段式名(
OtherDB.dbo.Table),否则referenced_database_name为NULL或空字符串,实际仍按当前库解析 - 查询示例:
SELECT referenced_entity_name, referenced_schema_name, referenced_database_name FROM sys.sql_expression_dependencies WHERE referencing_id = OBJECT_ID('dbo.usp_GetOrderSummary') AND is_ambiguous = 0;
为什么不能用 sys.dm_exec_describe_first_result_set?
它只模拟执行后第一个结果集的列定义,不扫描 T-SQL 文本里的 FROM、JOIN 或 INSERT INTO 目标。哪怕存储过程里写了 DELETE FROM Archive.Logs,这个 DMF 也完全无感。
- 它可能返回空结果,或只返回 SELECT 的字段名,和“依赖哪些表”毫无关系
- 对含多个结果集、条件分支(
IF @mode = 1 SELECT ... ELSE UPDATE ...)的存储过程,结果不可靠 - 性能开销略高,且需调用方有足够权限执行该过程(或至少能模拟执行)
查不到依赖?先确认这几个前提
依赖没出现在 sys.sql_expression_dependencies 里,大概率不是工具问题,而是元数据本身没注册。
- 执行查询的账号缺少
VIEW DEFINITION权限 —— 没这权限的对象,SQL Server 不会把它的依赖写入该视图 - 存储过程用了加密(
WITH ENCRYPTION)?不影响,sys.sql_expression_dependencies仍可用 - 对象刚建完或刚
ALTER过,但没触发依赖刷新?重启服务或执行sp_refreshsqlmodule可强制重建 - 引用写成双段名(
schema.object)且跨库?SQL Server 默认当成当前库对象处理,referenced_database_name字段为空,容易误判
真正难搞的是动态拼接和运行时决定的引用——这类根本不在元数据层面存在,只能靠人工扫代码、日志回溯或运行时 Profiler 捕获实际执行的语句。别指望系统视图能自动覆盖这部分。











