↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / SQL 状态码 / Class 23 完整性约束违反

23001 restrict_violation

RESTRICT 约束冲突

ERROR 已实测 详解 实测通过

类别
Class 23 完整性约束违反
严重等级
ERROR
条件名
restrict_violation
宏名称
ERRCODE_RESTRICT_VIOLATION
最早已知存在
7.4
状态
有效

版本覆盖

版本条依据已采样构建显示;灰色版本可能尚未采样,悬停可查看。手册链接随版本选择,源码和运行证据保持原核验构建。

速览

23001 是立即执行的外键 RESTRICT 动作导致的专用冲突。18.6 案例删除仍被引用的父行时返回该码;10.21 对同一操作返回 23503,必须记录版本和完整诊断。另一个 PostgreSQL 17.11 对照案例对该 RESTRICT 操作也返回 23503,不计作 23001 覆盖。

含义

ON DELETE/UPDATE RESTRICT 会立即检查引用行,且不能延迟;可延迟的 NO ACTION 则可以把检查推迟到相应提交点。源码根据父表、外键、子表和可见键值动态组装报文。

诊断

记录精确 SQLSTATE、constraint_name、表名和 DETAIL,先检查子表。显式事务删除失败后连接为 INERROR,必须 ROLLBACK,再在新的 BEGIN/COMMIT 中删除子行和父行。

处理

按完整性语义选择删除/改派依赖行、放弃父操作或重新设计 FK 动作。不要为了迁移方便把 RESTRICT 偷换成可延迟 NO ACTION。

可复现案例

在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。

restrict_delete_referenced_parent PG 18 有 SQL

前置条件

  • A child row references a parent through ON DELETE RESTRICT
  • The parent delete is attempted while the child remains

触发

Delete the referenced parent row.

断言

  • SQLSTATE is 23001
  • The RESTRICT constraint and referencing table are identified
  • Deleting the child first permits an explicit parent repair

处置

Resolve the dependent row according to business rules, then delete or retain the parent; changing RESTRICT to another action is a schema decision, not an error fix.

清理

Drop the case schema with an owner connection.

实测诊断

18.6 (Homebrew) / latest:SQLSTATE 23001;primary update or delete on table "parents" violates RESTRICT setting of foreign key constraint "children_parent_id_fkey" on table "children";DETAIL Key (id)=(1) is referenced from table "children".;after_error INERROR;after_rollback IDLE。 10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 23503;primary update or delete on table "parents" violates foreign key constraint "children_parent_id_fkey" on table "children";DETAIL Key (id)=(1) is still referenced from table "children".;after_error INERROR;after_rollback IDLE。 17.11 (pg17) / boundary:SQLSTATE 23503;primary update or delete on table "parents" violates foreign key constraint "children_parent_id_fkey" on table "children";DETAIL Key (id)=(1) is still referenced from table "children".;after_error INERROR;after_rollback IDLE;最终计数 [0, 0]。该边界案例不计作 23001 覆盖。

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 update or delete on table "%s" violates RESTRICT setting of foreign key constraint "%s" on table "%s"
DETAIL Key (%s)=(%s) is referenced from table "%s".

来源: 来源:src/backend/utils/adt/ri_triggers.c @ REL_18_6

适用范围:The privilege-aware branch can instead emit the source detail template without key values.

代表案例

运行器从 verify/cases/23001/snippets.json(SHA-256 6086c1ce982afa5438bbcd29b86ec4cd0cbe0c76fa6152c1eb4a330a7706d5c8)读取下列片段,并为临时 schema 替换表名;完整 setup、断言与清理见 案例导出。

-- create_parent
CREATE TABLE parents(id integer PRIMARY KEY);
-- create_child
CREATE TABLE children(id integer PRIMARY KEY, parent_id integer NOT NULL REFERENCES parents(id) ON DELETE RESTRICT);
-- seed_parent
INSERT INTO parents VALUES (1);
-- seed_child
INSERT INTO children VALUES (10, 1);
-- begin
BEGIN;
-- trigger
DELETE FROM parents WHERE id = 1;
-- rollback
ROLLBACK;
-- repair_begin
BEGIN;
-- repair_child
DELETE FROM children WHERE id = 10;
-- repair_parent
DELETE FROM parents WHERE id = 1;
-- commit
COMMIT;
-- verify
SELECT (SELECT count(*) FROM parents), (SELECT count(*) FROM children);

本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自上述共享 registry;结构化证据 · 案例导出。

作者证据 ID:identity、restrict-path、no-action-boundary、runtime、runtime.pg17-boundary。选定基础运行记录:runtime.23001-batch1-latest2-20260909.latest、runtime.23001-batch1-pg10b-20260909.pg10。单独的边界记录:runtime.23001-boundary-pg17-final-20260909.pg17。

版本与边界

锁定目录在 7.4 已观察到该条件,并在列出的正式快照中均存在。选定基础案例在 18.6 观察到 23001,在 10.21 对同一 RESTRICT 删除观察到 23503。另一个 PG17.11 边界对照也返回 23503,并保持 INERROR 到 IDLE 的恢复边界;该记录单独保留,不能推广为所有 PostgreSQL 11–17 小版本的普遍结果。

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed 案例:restrict_delete_referenced_parent
pg10 10.21 (Debian 10.21-1.pgdg90+1) not_applicable 案例:restrict_delete_referenced_parent
pg17 17.11 (Debian 17.11-1.pgdg13+2) not_applicable 案例:restrict_delete_referenced_parent

同类 SQL 状态码

状态码 条件名 宏名称 严重等级 版本
Class 23 完整性约束违反 Integrity Constraint Violation 7 个 ↗
23000 integrity_constraint_violation ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION ERROR 7.4 起已知
完整性约束冲突的类别码,应使用具体子码。 有效
23001 restrict_violation ERRCODE_RESTRICT_VIOLATION ERROR 7.4 起已知
外键 RESTRICT 动作拒绝删除仍被引用的父行。 有效
23502 not_null_violation ERRCODE_NOT_NULL_VIOLATION ERROR 7.4 起已知
向 NOT NULL 列写入了 NULL 值。 有效
23503 foreign_key_violation ERRCODE_FOREIGN_KEY_VIOLATION ERROR 7.4 起已知
外键约束冲突,子行找不到匹配的父键。 有效
23505 unique_violation ERRCODE_UNIQUE_VIOLATION ERROR 7.4 起已知
行或索引违反唯一约束,常见于重复键插入。 有效
23514 check_violation ERRCODE_CHECK_VIOLATION ERROR 7.4 起已知
CHECK 约束计算为假,写入的行不满足条件。 有效
23P01 exclusion_violation ERRCODE_EXCLUSION_VIOLATION ERROR 9.0.0 起已知
排除约束发现新行与已有行冲突,如范围重叠。 有效