# 22030 — duplicate_json_object_key_value

> PostgreSQL SQLSTATE 22030 的来源与诊断参考。
---

# 22030

## 速览 {#at-a-glance}
构造 JSON 对象时遇到重复键。固定的 JSON 唯一键构造器和聚合路径报告 `duplicate JSON object key value: %s`；JSONB 对象收尾有相关变体。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22030` |
| 条件名 | `duplicate_json_object_key_value` |
| 状态 | `有效` |
| 已知存在于 | `12.0` |
| 锁定快照 | `12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE` |
| 别名 | `—` |

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

## 报文 {#messages}
唯一键路径使用以下首要文本：

| 路径 | 首要文本 |
| --- | --- |
| 启用唯一键的 JSON 构造器或聚合 | `duplicate JSON object key value: %s` |
| JSONB 对象收尾或唯一键校验 | `duplicate JSON object key value` |

## 含义 {#meaning}
当 JSON 对象操作明确启用键唯一性，并在同一对象中再次遇到同名键时，会报告 22030。JSON 构造器和对象聚合携带 `unique_keys` 标志；唯一键变体记录已见键，并在插入或对象收尾时报告错误。普通 `json`/`jsonb` 输入将该标志设为 false，普通构造器或聚合也不会把输入文本中的每个重复键都变成 22030。strict 或 absent-on-null 变体会从输出中省略 NULL 值，但唯一键变体仍会保留键并检查唯一性，因此即使值将被跳过，重复键仍可能失败。对象键本身为 NULL 属于独立的参数错误。

## 诊断 {#diagnosis}
确认构造器或聚合，以及其文档规定的形式是否强制唯一键。JSON 构造器/聚合路径的 `%s` 报文会给出重复键；JSONB 收尾和校验路径使用较短的首要文本。区分重复键策略、无效 JSON 语法、NULL 对象键，以及按普通语义允许重复输入的 `json`/`jsonb` 解析。

## 处理 {#response}
按所属实现的重复键策略处理：需要唯一性时在上游去重或汇总；只有在确实要保留重复键语义时，才使用文档规定的非唯一操作。不要通过修改唯一键标志来解决 NULL 键或格式错误的 JSON。如果 ERROR 发生在显式事务中，应先 ROLLBACK 或回滚到既有保存点再重试；自动提交可重试修正后的动作。

## 版本 {#versions}
锁定目录从 12.0 起记录该条件；本页固定 JSON 和 JSONB 源码路径为 PostgreSQL 18.6。未声称本页有自然运行观察。

## 相关 {#related}
[`22032`](../22032/)、[`22023`](../22023/)

## 来源 {#sources}
JSON 唯一键构造器和聚合见 [`src/backend/utils/adt/json.c#L1002-1127`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/json.c#L1002) 和 [`#L1224-1295`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/json.c#L1224)；JSON 唯一性校验见 [`#L1810-1853`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/json.c#L1810)。JSONB 普通输入在 [`src/backend/utils/adt/jsonb.c#L74-102`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonb.c#L74) 中关闭唯一性；唯一键构造和对象收尾见 [`#L1125-1163`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonb.c#L1125) 与 [`src/backend/utils/adt/jsonb_util.c#L1952-2005`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonb_util.c#L1952)。结构化[证据记录](../../data/evidence/22030.json)保留唯一键和 NULL 跳过边界；本页未运行自然案例。
