# 42P08 — 参数类型不明确

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

# 42P08 — 参数类型不明确

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

`42P08`（**ambiguous_parameter**）表示参数标记存在，但解析阶段无法把它解析为一致或足够具体的类型。由于相似主消息也可能来自其他条件，必须结合 SQLSTATE 和源码分支判断。

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

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

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

## 含义 {#meaning}

可变参数强制转换钩子会先为未知参数记录目标类型；后续上下文要求另一类型时，报告 ERROR `inconsistent types deduced for parameter $%d`，DETAIL 为 `%s versus %s`。随后参数解析检查发现解析出的类型与外部类型数组不一致时，报告 ERROR `could not determine data type of parameter $%d`。这是两条选定的 `42P08` 检查，不是笼统的“绑定失败”。

相同的 `could not determine data type of parameter $%d` 主消息也会在 `postgres.c` 的可变参数完成检查中配合 `ERRCODE_INDETERMINATE_DATATYPE`（`42P18`）发出。应同时读取 SQLSTATE 和源码路径：本页 `42P08` 是参数解析阶段的类型不匹配，`42P18` 是解析完成后仍未确定类型，超出范围的标记则是 `42P02`。

## 诊断 {#diagnosis}

记录参数编号、所有表达式上下文和 DETAIL。对于类型不一致分支，对照 DETAIL 中的两种类型，找到分别施加约束的上下文；对于未确定分支，检查 PREPARE/扩展查询的参数类型数组和最终推导类型。缺少标记（`42P02`）、Bind 数量违反协议（`08P01`）以及别名/列歧义不应混入此类型解析问题。

## 处理 {#response}

在明确的表达式边界声明参数类型或转换类型。两个上下文确实需要不同类型时拆分参数，否则统一上下文类型。不要随意转换成宽泛类型，随后核对运算符、索引、NULL 语义和序列化。若 `ERROR` 发生在显式事务中，应回滚到合适保存点或回滚事务再重试。

## 消息变体 {#messages}

选定的 `42P08` 变体均为 `ERROR`：

| 检查 | 主消息 | DETAIL |
| --- | --- | --- |
| 推导目标类型冲突 | `inconsistent types deduced for parameter $%d` | `%s versus %s` |
| 最终参数类型不匹配 | `could not determine data type of parameter $%d` | 无 |

第二条主消息也可能来自独立的 `42P18` 未确定类型检查；SQLSTATE 是报文身份的一部分。

## 版本 {#versions}

目录范围从 7.4 到 18.6、19beta3，不是精确的功能引入判断。选定的是两条 `42P08` 检查和相邻的 `42P18` 边界源码，未运行参数案例。

## 相关 {#related}

- [`42P02`](../42p02/)
- [`42P09`](../42p09/)
- [`42804`](../42804/)

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

- `src.call.42P08.c2cfa81ed9389a1bddf8ec41` — `src/backend/parser/parse_param.c` lines 220-227，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `4aab2ecc770fcda619b26ac12beaf7e527542b56f55eb45879b72e92442e8a28`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_param.c#L220-L227)）。
- `src.call.42P08.18ba6576d169dfdf614df72d` — `src/backend/parser/parse_param.c` lines 308-312，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `4aab2ecc770fcda619b26ac12beaf7e527542b56f55eb45879b72e92442e8a28`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_param.c#L308-L312)）。
- `src.call.42P08.unresolved-boundary` — `src/backend/tcop/postgres.c` lines 725-736，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `9fb62275b1badf94d01ab351337b60410cd9b3ab1fe63fa9f23d6d2185a21061`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L725-L736)）。
- `src.calls.REL_18_6.42P08` — 固定本地核心调用扫描；SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`。
- [`作者证据`](../../data/evidence/42p08.json) — 记录源码断言、消息角色和运行边界。
