# 42P14 — 无效预备语句定义

> PostgreSQL SQLSTATE 42P14：来源与诊断参考。
---

# 42P14 — 无效预备语句定义

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

`42P14`（**invalid_prepared_statement_definition**）PREPARE 命令可能在定义预备语句时失败。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `42P14` |
| 条件名 | `invalid_prepared_statement_definition` |
| 状态 | `有效` |
| 已知存在于 | `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_INVALID_PSTATEMENT_DEFINITION` |
| 别名 | `—` |

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

## 含义 {#meaning}

固定的 18.6 `PrepareQuery` 路径在注册命名预备语句前，拒绝 SQL `PREPARE` 的空名称或空指针；这是因为扩展协议有独立的 unnamed 语句槽。因此，协议 `Parse` 消息中的空名称不自动等于 `42P14`，空的 SQL 引用标识符也可能先在词法或解析阶段失败。

## 诊断 {#diagnosis}

准确记录客户端发送的是 SQL `PREPARE` 还是扩展协议 `Parse`，并保留语句名。区分 SQL PREPARE 的空名称检查、合法的协议 unnamed 语句、26000（预备语句不存在）以及后续参数/类型错误；空的引用标识符可能在到达此 guard 前就失败。

## 处理 {#response}

SQL `PREPARE` 应使用非空且引用方式一致的语句名。扩展协议若本来要使用 unnamed 语句槽，就保留该协议语义，不要改写成 SQL `PREPARE`。若名称由框架生成，检查命名层，并确认后续 EXECUTE 与 DEALLOCATE 使用同一会话。显式事务中的 ERROR 之后，下一条命令前仍需 `ROLLBACK` 或回滚到错误前的保存点。

## 消息 {#messages}

固定源码中的代表性消息为：`invalid statement name: must not be empty`（ERROR；没有占位符）。

## 版本 {#versions}

锁定目录显示该条件最早见于 PostgreSQL 7.4；行为说明固定在 PostgreSQL 18.6 源码，目录存在范围不等于每条消息或功能都从该版本开始。

## 相关 {#related}

- [`42P05`](../42p05/)
- [`26000`](../26000/)

## 来源 {#sources}

源码消息、行号和证据边界见 [作者证据](../../data/evidence/42p14.json)。

- `src/backend/commands/prepare.c:73-75` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L73-L75))
- `src/backend/tcop/postgres.c:1433-1459` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L1433-L1459))
