如何识别非架构绑定依赖?继承数据库依赖排查困惑
理解Non-schema-bound Dependency:看不见的数据库依赖
我经常碰到接手老数据库时遇到这种“隐形”依赖的情况,给你拆解一下这个问题:
什么是Non-schema-bound Dependency?
简单说,这是一种软依赖——依赖对象(比如你的Table1)和被依赖的表之间,没有强制的架构绑定关系。和外键、CHECK约束这种硬绑定不同,硬绑定的话,你要是改了被依赖表的结构(比如删个字段),依赖它的对象会直接报错;但非架构绑定的依赖不会,被依赖表的结构可以随意修改,不会直接触发数据库的报错。
哪些场景会产生这种依赖?
这种依赖通常来自不是直接通过表结构关联的数据库对象,常见的有这些:
- 动态SQL:比如Table1关联的存储过程、触发器里,用了
EXEC('SELECT * FROM 依赖表 WHERE ID = ' + @ID)这种拼接出来的SQL,数据库会追踪到这个依赖,但它不是硬绑定的。 - 非架构绑定的函数/视图:如果有函数是用
CREATE FUNCTION ... WITHOUT SCHEMABINDING创建的,里面引用了那些依赖表;或者视图用了WITHOUT SCHEMABINDING,那这些引用都会被标记为非架构绑定依赖。 - 计算列的子查询引用:Table1里如果有计算列,表达式里用了类似
(SELECT Name FROM 依赖表 WHERE ID = dbo.Table1.ID)的子查询,这种也会产生非架构绑定依赖。 - 间接引用:比如Table1引用了一个同义词,同义词指向依赖表;或者Table1引用了一个视图,视图又引用了依赖表,且视图是非架构绑定的。
怎么识别这些隐藏的依赖?
光看表创建语句和ER图肯定找不到,得用数据库的系统工具和代码检查:
用系统视图精准查询
用SQL Server的系统视图可以直接列出所有依赖关系,包括是否是架构绑定的。比如:-- 查询Table1引用的所有对象,明确是否为非架构绑定 SELECT referenced_entity_name AS 被依赖对象名, referenced_minor_name AS 被依赖字段, is_schema_bound_reference AS 是否架构绑定 FROM sys.dm_sql_referencing_entities('dbo.Table1', 'OBJECT')或者反过来,查哪些对象引用了那个“神秘”的依赖表:
SELECT referencing_entity_name AS 依赖对象名, referencing_class_desc AS 对象类型(表/存储过程/函数等), is_schema_bound_reference AS 是否架构绑定 FROM sys.dm_sql_referenced_entities('dbo.你的依赖表名', 'OBJECT')另外
sys.sql_expression_dependencies视图也能查到这些信息,重点看is_schema_bound列。检查Table1关联的数据库对象
- 先看Table1上的触发器:右键Table1查看所有触发器,逐行检查代码,看有没有引用那些依赖表的动态SQL或者非绑定函数。
- 搜索数据库里的存储过程、用户定义函数:用数据库的搜索功能,找包含Table1和依赖表名称的对象,重点看带动态SQL的部分。
- 检查Table1的计算列:查看表设计里的计算列,看表达式是否引用了其他表的内容。
排查间接依赖
如果上面的方法没找到,就查一下有没有同义词、非绑定视图在中间做中转——比如Table1引用了一个视图,而这个视图引用了那个依赖表,这种情况也会被标记为Table1对依赖表的非架构绑定依赖。
总的来说,这种依赖是数据库对“软引用”的追踪,不会在表结构里体现,得从代码层面和系统视图入手才能找到根源。
内容的提问来源于stack exchange,提问作者jamheadart
相关产品推荐
相关产品推荐

