# 22P02 — 文本表示无效

> PostgreSQL SQLSTATE 22P02（文本表示无效，invalid_text_representation）的源码证据、诊断与处理参考。
---

# 22P02 — 文本表示无效

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

`22P02` 表示文本输入例程无法把值解释为目标类型。本页选择普通整数输入路径，同时标出 COPY/文本边界；COPY、枚举、扩展和 contrib 调用可能使用不同主报文。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22P02` |
| 条件名 | `invalid_text_representation` |
| 状态 | `有效` |
| 已知存在于 | `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_TEXT_REPRESENTATION` |
| 别名 | `—` |

<!-- source facts: data/errcodes/22P02.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

cast、赋值或文本 `COPY` 字段由目标类型的输入例程判断文本是否合法。PostgreSQL 18.6 使用 `invalid input syntax for type integer: "%s"`，锁定的 PostgreSQL 10.23 源码使用 `invalid input syntax for integer: "%s"`；两者都是动态模板，也不是统一的本地化字符串。其他固定调用者还包括 COPY reject-limit、枚举输入和扩展校验，因此 primary 文本和上下文可能不同。

## 诊断 {#diagnosis}

记录目标类型、客户端编码和参数绑定后的原始值，并确认操作是 cast、赋值、文本 `COPY` 字段、枚举输入还是其他类型包装。把坏文本（`22P02`）与数值越界（`22003`）、日期时间语法错误（`22007`）、二进制表示无效（`22P03`）以及 COPY 文件/头部或 framing 错误（`22P04`）区分开。二进制 COPY payload 不能只按文本输入报文诊断。

## 处理 {#response}

在输入边界校验并保持预期目标类型。只有修正值后才重试；除非业务规则明确要求，不要静默截断或把值变成 NULL。显式事务中的输入 ERROR 会使事务进入中止状态（`25P02`）；继续前执行 `ROLLBACK`，或使用 `ROLLBACK TO SAVEPOINT convert_input`。COPY 出错后也必须先恢复事务，再执行下一条命令。

## 实测诊断 {#messages}

普通整数路径固定为 `ERROR`，并有上述版本差异的动态主报文。选定实测记录了精确值：`"not-an-integer"` 产生 22P02，同一自动提交会话随后把合法 `"42"` 转换为 42。

## 代表案例 {#case}

共享注册表在自动提交下先发送一次无效文本 cast，检查真实诊断和 `IDLE` 状态，再在同一连接发送合法整数文本。这个实测恢复不同于显式事务；后者必须先回滚或回滚到保存点。页面 SQL 与运行器来自同一注册表，没有隐藏的第二定义。

<!-- BEGIN SQLSTATE SNIPPET: invalid_integer_text -->

```sql
SELECT 'not-an-integer'::integer;
SELECT '42'::integer
```

<!-- END SQLSTATE SNIPPET -->

选定的 PostgreSQL 18.6 与 10.21 运行均通过 SQLSTATE、严重级别、状态或断开恢复、修复、清理和一次性实例停止断言。详见 [`案例 JSON`](../../data/cases/22p02.json) 与 [`作者证据`](../../data/evidence/22p02.json)。

## 版本 {#versions}

锁定目录从 7.4 起记录 22P02。18.6 与 10.21 的有界运行均通过，但主报文措辞如上有所不同；这不能推广到所有 22P02 调用方或所有中间版本。

## 相关 {#related}

- [`22003`](../22003/)
- [`22007`](../22007/)
- [`22P03`](../22p03/)
- [`22P04`](../22p04/)

## 来源 {#sources}

- `src.errcodes.18.6` — `src/backend/utils/errcodes.txt` at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; blob SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L206)).
- `src.invalid-integer.18.6` — `src/backend/utils/adt/numutils.c` at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; blob SHA-256 `9018d559d8a2b04f6d3fa8fedeb754fc5f1f8cd8594292e6adc5108e8f97f1bf` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numutils.c#L614-L618)).
- `src.invalid-integer.10.23` — `src/backend/utils/adt/numutils.c` at `02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4`; blob SHA-256 `6cb3fd7e4b38a66c16f2cc4a3de0c52ce44e01dd22edd3dd9340d2a8faea0d35` ([source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/utils/adt/numutils.c#L59-L62)).
- `src.copy-text.18.6` — 固定文本 COPY 转换/reject-limit 路径位于 `src/backend/commands/copyfrom.c` 第 1169-1172 行（[来源](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfrom.c#L1169-L1172)）。
- `src.calls.REL_18_6` / `src.calls.REL_10_23` — fixed call scans, SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf` / `00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c`.
- `manifest.22P02` / `snippet-registry.22P02` — hashes are recorded in `evidence/22P02.json` and each selected runtime record.
