应使用sys.sql_expression_dependencies查询视图引用关系,因其准确记录静态依赖;sp_depends已过时且不可靠;动态SQL需手动扫描sys.sql_modules.definition;WITH SCHEMABINDING可增强依赖可靠性但限制修改。

查视图被哪些存储过程、函数或其它视图引用
SQL Server 不直接记录“谁调用了这个视图”,但能查出哪些对象在定义里显式引用了它——这是唯一可靠的元数据方式。关键不是看运行时调用链,而是看 sys.sql_expression_dependencies 里存的静态依赖关系。
-
sys.sql_expression_dependencies是首选,它会告诉你哪些存储过程(type = 'P')、函数('FN'、'IF'、'TF')或其它视图('V')在定义中写了这个视图名 - 必须用带 schema 的完整名查询,比如
'dbo.MyView',否则可能漏掉跨 schema 引用 - 动态 SQL 中的引用查不到,例如
EXEC('SELECT * FROM dbo.MyView')不会被捕获——这种只能靠全文扫描sys.sql_modules.definition - 结果里的
referencing_schema_name和referencing_entity_name就是调用方的 schema 和名字
示例:查所有引用 dbo.CustomerSummary 视图的对象
SELECT DISTINCT
OBJECT_SCHEMA_NAME(d.referencing_id) AS referencing_schema,
OBJECT_NAME(d.referencing_id) AS referencing_name,
o.type_desc AS object_type
FROM sys.sql_expression_dependencies d
JOIN sys.all_objects o ON d.referencing_id = o.object_id
WHERE d.referenced_id = OBJECT_ID('dbo.CustomerSummary')
AND o.is_ms_shipped = 0;为什么不能只用 sp_depends
sp_depends 已被标记为“过时”,SQL Server 2005 起就不再更新其内部逻辑,对新语法(如 CTE、窗口函数、WITH RESULT SETS)支持差,且不区分引用层级——它可能把仅在注释里出现的视图名也当真依赖。
- 返回结果不稳定:同一视图多次执行
sp_depends可能给出不同对象列表 - 不支持跨数据库引用(即使你用三段式名
db.schema.view调用,它也常忽略db部分) - 无法过滤类型,比如你想只看存储过程,它仍会混入函数和触发器
- 官方文档明确建议改用
sys.sql_expression_dependencies
动态 SQL 场景下怎么补救
如果目标视图确实被大量 EXEC(...) 或 sp_executesql 调用,sys.sql_expression_dependencies 就会为空。这时得手动翻定义:
- 用
OBJECT_DEFINITION(object_id)拿到所有非系统对象的完整定义文本 - 匹配
FROM.*?CustomerSummary或JOIN.*?CustomerSummary这类模式(注意要加WITH前缀的干扰,比如WITH CustomerSummary AS (是误报) - 别忘了检查
sys.views本身——有些视图是嵌套引用,A → B → CustomerSummary,而 A 并未直接写 CustomerSummary - 权限影响:用户必须对目标对象有
VIEW DEFINITION权限,否则OBJECT_DEFINITION()返回 NULL
简单筛选示例(查定义含 CustomerSummary 的存储过程):
SELECT
SCHEMA_NAME(o.schema_id) AS schema_name,
o.name AS object_name
FROM sys.all_objects o
JOIN sys.sql_modules m ON o.object_id = m.object_id
WHERE o.type IN ('P', 'FN', 'IF', 'TF', 'V')
AND o.is_ms_shipped = 0
AND m.definition LIKE '%CustomerSummary%';WITH SCHEMABINDING 对依赖发现的影响
如果视图是用 WITH SCHEMABINDING 创建的,它的依赖关系更可靠;但反过来,它也会阻止你删改被引用的列或表——这会让依赖“卡死”在元数据里,即使逻辑上已废弃。
- 没加
SCHEMABINDING的视图,sys.sql_expression_dependencies仍能查到引用,但字段级变动不会触发错误,容易埋雷 - 加了
SCHEMABINDING后,视图定义被锁定,sys.dm_sql_referenced_entities能返回更精确的列级引用,但代价是修改底层表前必须先删/改视图 - 真正难排查的是“半绑定”状态:视图创建时有
SCHEMABINDING,但后来被ALTER VIEW去掉了——元数据里is_schema_bound字段会变,但旧依赖记录不会自动清理
确认是否绑定:SELECT is_schema_bound FROM sys.views WHERE name = 'CustomerSummary'

















