文档 / SQL 状态码 / Class 2B 依赖权限描述符仍存在
2BP01 dependent_objects_still_exist
依赖对象仍存在
ERROR 已实测 详解 实测通过
- 条件名
dependent_objects_still_exist- 宏名称
ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
2BP01 表示 DROP 或相关目录操作要移除的对象仍被其他数据库对象依赖。正确处理是先理解依赖关系,决定依赖对象应保留还是删除,再重试原操作。
含义
依赖遍历器会在对象仍被其他对象需要时发出 2BP01。代表路径中视图依赖表,因此 DROP TABLE 不能执行。主报文、DETAIL 和 CASCADE 提示都根据对象描述和依赖图动态组装。2BP01 讨论的是依赖对象;依赖权限描述符的 2B000 是另一种条件。
诊断
同时保存 SQLSTATE、主报文、DETAIL 和 HINT。选定路径的 DETAIL 会指出依赖视图。选择修复前检查视图定义和依赖元数据;pg_depend 与 pg_get_viewdef() 可以说明对象为什么仍被保留。在选定的显式 BEGIN 块中,收到该 ERROR 后连接会在 ROLLBACK 前处于 INERROR;自动提交语句没有需要保留的外层事务。不能在失败的显式块中继续查询目录来完成可靠诊断。
处理
先回滚失败的显式事务。如果视图确实可以删除,先删视图,再删表;如果视图属于模式契约,就保留它并改写迁移方案。CASCADE 是删除依赖对象的明确请求,可能超过预期变更,因此不能把 HINT 自动当成执行指令。完成有边界的修复后,重新执行完整 DDL 计划并核对仍应存在的对象。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
dependent_object_drop_recovery PG 10 / 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
Create a view that depends on a table, attempt DROP TABLE inside an explicit transaction, then drop the view first and the table.
断言
- SQLSTATE is 2BP01
- The diagnostic names dependent objects
- The failed transaction is INERROR until ROLLBACK
- Dropping the dependent view first removes both objects without CASCADE
处置
Rollback the failed DROP, inspect the named dependent objects, and remove them in an intentional dependency order.
清理
Drop the case schema with an owner connection.
报文
选定源码分支的模板为 cannot drop %s because other objects depend on it,DETAIL 是动态内部文本,HINT 为 Use DROP ... CASCADE to drop the dependent objects too.。对象描述和依赖列表都是运行时值,不要把 DETAIL 当成固定的单对象模板,也不要假设所有 2BP01 路径都使用同一措辞。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
cannot drop %s because other objects depend on it
%s (dynamic internal detail)
Use DROP ... CASCADE to drop the dependent objects too.
来源:src/backend/catalog/dependency.c @ REL_18_6
适用范围:Object descriptions and dependency detail are dynamically assembled.
代表案例
运行器从 verify/cases/2BP01/snippets.json(SHA-256 899e4fd9fb002fc293bd9efee0204e4f2622968c6d9460ad05eb9a0ebd3bac69)读取下面的依赖序列;失败 DROP 使用显式 BEGIN/ROLLBACK,修复先删已知视图再删表,完全不使用 CASCADE。见公开案例导出和结构化证据。
CREATE TABLE base_items(id integer PRIMARY KEY, payload text NOT NULL);
CREATE VIEW dependent_view AS SELECT id, payload FROM base_items;
BEGIN;
DROP TABLE base_items;
ROLLBACK;
DROP VIEW dependent_view;
DROP TABLE base_items;
SELECT to_regclass('base_items'), to_regclass('dependent_view');
运行器会在私有 schema 中为 registry 名称加限定名。最后两个 to_regclass 都返回 null,证明删除的是预期对象,而不是对未知依赖图静默级联。
选定案例在 PostgreSQL 18.6 和 10.21 观察到 2BP01。DROP TABLE 的 DETAIL 指出依赖视图并给出 CASCADE 提示;显式事务进入 INERROR,ROLLBACK 恢复为 IDLE,随后先删视图再删表完成修复。
版本
目录从早期历史边界到正式快照都记录了该条件。18.6 固定源码还包括依赖、共享依赖、角色、权限、类型表和表空间等分支;运行案例只覆盖 18.6 与 10.21 的普通视图到表依赖。不能据此推断所有分支的 CASCADE 都安全。
来源
- 上游源码 doc/src/sgml/ref/drop_table.sgml
- 上游源码 src/backend/catalog/dependency.c 第 1148–1154 行
- 上游源码 src/backend/utils/errcodes.txt
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
2BP01 is the dependent_objects_still_exist condition in Class 2B.
-
The dependency walker reports that an object cannot be dropped while other objects depend on it and supplies a CASCADE hint.
-
A safe repair identifies the dependent view and drops it intentionally before dropping its base table; CASCADE is an explicit policy choice, not a universal repair.
-
The selected 2BP01 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | dependent_object_drop_recovery |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | dependent_object_drop_recovery |
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| 2B000 | dependent_privilege_descriptors_still_exist | ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST |
ERROR | 7.4 |
| 仍存在依赖的权限描述符,对象依赖见 2BP01。 | 活跃 | |||
| 2BP01 | dependent_objects_still_exist | ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST |
ERROR | 7.4 |
| DROP 的对象仍被其他数据库对象依赖。 | 活跃 | |||