# 23P01 — 排除约束冲突（exclusion_violation）

> PostgreSQL SQLSTATE 23P01：排除约束冲突的来源与诊断参考。
---

# 23P01 — 排除约束冲突

## 速览 {#at-a-glance}

`23P01` 表示排除约束发现已有行与新行在所有配置运算符上冲突。本案例使用 `&&` 检查范围重叠，因此拒绝的是重叠而不只是相等值。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `23P01` |
| 条件名 | `exclusion_violation` |
| 状态 | `有效` |
| 已知存在于 | `9.0.0` |
| 锁定快照 | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_EXCLUSION_VIOLATION` |
| 别名 | `—` |

<!-- source facts: data/errcodes/23P01.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

排除约束结合索引访问方法和运算符；`[5,12)` 与 `[1,10)` 重叠，而半开范围 `[10,12)` 在 10 处不重叠。运算符类和约束配置的运算符组合决定冲突；DEFERRABLE 会改变检查时点。

## 诊断 {#diagnosis}

记录约束名、DETAIL 中的键值，以及约束是否延迟。按相同运算符检查现有行，不能只做相等比较。立即约束在语句边界报错，DEFERRABLE 约束可能在 `SET CONSTRAINTS` 或 `COMMIT` 时才报错。本案例是立即检查、自动提交，错误后连接为 `IDLE`。

## 处理 {#response}

选择不冲突的值，或按应用并发策略协调冲突的预订或资源。自动提交时，失败语句结束自己的事务边界，连接可以继续使用。显式事务中，无论立即检查还是延迟检查报错，都可能使事务进入失败状态；重试前应执行 `ROLLBACK`，若应用刻意用保存点隔离该操作，则可执行 `ROLLBACK TO SAVEPOINT` 保留外层事务。DEFERRABLE 冲突可能在 `SET CONSTRAINTS` 或 `COMMIT` 才报告，因此应从该检查时点要求的干净边界重做完整操作；只有冲突确实可能消失且操作安全时才重试。不要脱离业务规则随意改范围端点。

## 实测诊断 {#messages}

`18.6 (Homebrew) / latest`：SQLSTATE `23P01`；primary `conflicting key value violates exclusion constraint "bookings_no_overlap"`；DETAIL `Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).`；status_after_error `IDLE`。
`10.21 (Debian 10.21-1.pgdg90+1) / pg10`：SQLSTATE `23P01`；primary `conflicting key value violates exclusion constraint "bookings_no_overlap"`；DETAIL `Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).`；status_after_error `IDLE`。

## 代表案例 {#case}

本例第二个预订与已有范围重叠；把下界移到已有范围的上界即可修复。完整 setup、断言与清理见[案例导出](../../data/cases/23p01.json)：

<!-- BEGIN SQLSTATE SNIPPET: overlapping_range_exclusion -->
```sql
-- create
CREATE TABLE bookings(id integer PRIMARY KEY, during int4range NOT NULL, CONSTRAINT bookings_no_overlap EXCLUDE USING gist (during WITH &&));
-- seed
INSERT INTO bookings VALUES (1, int4range(1, 10));
-- trigger
INSERT INTO bookings VALUES (2, int4range(5, 12));
-- repair
INSERT INTO bookings VALUES (2, int4range(10, 12));
-- verify
SELECT id, during::text FROM bookings ORDER BY id;
```
<!-- END SQLSTATE SNIPPET -->

本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自经核对的案例 registry；见[结构化证据](../../data/evidence/23p01.json)和[案例导出](../../data/cases/23p01.json)。

作者证据 ID：`identity`, `mechanism`, `runtime`。选定运行记录：`runtime.23P01-batch1-latest-20260909.latest`, `runtime.23P01-batch1-pg10-20260909.pg10`。

## 版本与边界 {#versions}

锁定目录从 9.0.0 起观察到 `23P01`，并在列出的正式快照中均存在。选定的立即范围案例在 18.6 与 10.21 通过；未测试延迟或并发排除检查。

## 相关 {#related}

对比 [23505 唯一约束冲突](../23505/)、[23514 CHECK 冲突](../23514/) 和 [23001 RESTRICT 冲突](../23001/)。

## 来源 {#sources}

- [`src.errcodes.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt) (SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba`)
- `src.calls.REL_18_6` (SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`)
- [`src.execIndexing.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/execIndexing.c#L917-L937) (SHA-256 `24c80553ab4b28d7d2a288dd9196c8db9459c7f308853cd8c8c939485e15f199`)
- [`doc.rangetypes.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/rangetypes.sgml#L540-L573) (SHA-256 `cfeffb134d2acc2ec45141726583b041410665c4a2f8ecf66cd3f9484a7f0014`) · [官方文档](https://www.postgresql.org/docs/18/rangetypes.html#RANGETYPES-CONSTRAINT)
