# 20000 — case_not_found

> PostgreSQL SQLSTATE 20000 的源码与诊断参考。
---

# 20000

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

SQLSTATE 20000 在 PL/pgSQL 的 `CASE` 语句没有匹配任何 `WHEN` 且没有 `ELSE` 时报告。PostgreSQL 18.6 的消息是 `case not found`，hint 为 `CASE statement is missing ELSE part.`。该条件属于过程式 CASE 语句路径，不是普通查询返回零行的结果。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `20000` |
| 条件名 | `case_not_found` |
| 状态 | `有效` |
| 已知存在于 | `8.4.0` |
| 锁定快照 | `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_CASE_NOT_FOUND` |
| 别名 | `—` |

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

## 含义 {#meaning}

执行器路径位于 `src/pl/plpgsql/src/pl_exec.c` 的 `exec_stmt_case`。它执行搜索式或简单过程式 CASE 语句，在到达缺失 ELSE 的分支时报告 20000。SQL CASE 表达式语义不同，因此应先确认语句形式和例程源码，再修改查询。

## 消息 {#messages}

固定消息是 `case not found`；hint 为 `CASE statement is missing ELSE part.`。

## 诊断 {#diagnosis}

找到 routine context 指出的 PL/pgSQL 例程和 `CASE` 语句。列出选择值或谓词的可能结果，确认每个预期路径都有 `WHEN`，再检查是否遗漏 `ELSE`。不要用行数检查或 `SELECT INTO STRICT` 的诊断替代这个条件。

## 处理 {#response}

增加实现预期回退行为的 `ELSE` 分支，或使 `WHEN` 谓词覆盖所有可能值，并用代表性选择值验证例程。如果缺失分支代表无效业务输入，应由该分支有意报告应用条件。修改例程后，只有确认周围事务的副作用已回滚或业务操作具备幂等性时，才重新执行事务。

## 版本 {#versions}

锁定目录将该条件的已知下界记为 PostgreSQL 8.4.0。事实块列出已发布快照；源码路径状态仅限于下方固定的 PostgreSQL 18.6 资料。

## 相关 {#related}

[`02000`](../02000/), [`P0001`](../p0001/)

## 来源 {#sources}

固定的 [PL/pgSQL 执行器](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/pl/plpgsql/src/pl_exec.c#L2627-L2630)包含消息和 hint。[PL/pgSQL CASE 语句文档](https://www.postgresql.org/docs/18/plpgsql-control-structures.html#PLPGSQL-CONDITIONALS)说明缺少 ELSE 时的行为。 详见结构化[证据记录](../../data/evidence/20000.json)，其中记录固定源码路径、扫描范围和未解决的运行边界。
