# 42P05 — 重复预备语句

> PostgreSQL SQLSTATE 42P05（duplicate_prepared_statement）的来源与诊断参考。
---

# 42P05 — 重复预备语句

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

`42P05`（**duplicate_prepared_statement**）表示当前后端/会话已有同名服务器端预备语句。连接池可能让后续请求复用这段状态，而另一条连接可以拥有同名的独立语句。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `42P05` |
| 条件名 | `duplicate_prepared_statement` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `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_DUPLICATE_PSTATEMENT` |
| 别名 | `—` |

<!-- source facts: data/errcodes/42P05.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

`StorePreparedStatement` 把命名语句放在当前后端的 `prepared_queries` 哈希表中；`HASH_ENTER` 发现名称已存在时，在保存新计划前报告 ERROR `prepared statement "%s" already exists`。`DEALLOCATE name` 删除当前后端的一项，`DEALLOCATE ALL` 删除当前后端的全部项；它们不会删除另一条连接拥有的语句。

## 诊断 {#diagnosis}

检查物理连接/后端身份、`pg_prepared_statements`、连接池签出历史和 PREPARE 路径，区分命名服务器语句、未命名协议语句和驱动本地缓存键。若多个请求复用了同一连接，先核对准确名称和参数类型再修改 SQL。

## 处理 {#response}

只有 SQL 与参数类型匹配时才复用现有语句；否则由该连接的所有者协调 `DEALLOCATE name`、使用确定性的唯一名称，或按连接池生命周期策略重置会话。不要在另一条连接执行 DEALLOCATE 后假定冲突已清除。此 `ERROR` 若发生在显式事务中，应回滚保存点或回滚事务；重连只是受控重置，不是通用修复。

## 消息变体 {#messages}

确认的 18.6 变体是 `ERROR`：`prepared statement "%s" already exists`；`%s` 是动态的服务器端名称。

## 版本 {#versions}

目录范围从 7.4 到 18.6、19beta3，不是精确的功能引入判断。选定的 18.6 源码覆盖当前后端的插入与释放路径，未运行数据库。

## 相关 {#related}

- [`26000`](../26000/)
- [`42P04`](../42p04/)
- [`42P07`](../42p07/)

## 来源 {#sources}
- `src.errcodes.42P05.18.6` — `src/backend/utils/errcodes.txt` line 381，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L381)）。

- `src.call.42P05.b490336894ec11628c1766f2` — `src/backend/commands/prepare.c` lines 412-415，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L412-L415)）。
- `src.call.42P05.lifecycle` — `src/backend/commands/prepare.c` lines 401-423、504-511，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L401-L423)）。
- `src.calls.REL_18_6.42P05` — 固定本地核心调用扫描；SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`。
- [`作者证据`](../../data/evidence/42p05.json) — 记录源码断言、消息角色和运行边界。
