# 42704 — 未定义对象（undefined_object）

> PostgreSQL SQLSTATE 42704（未定义对象，undefined_object）的源码证据、诊断与处理参考。
---

# 42704 — 未定义对象

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

SQLSTATE `42704` 是 Class `42` 中的 **undefined_object**。`42704` 表示未定义对象。选定 DROP TRIGGER 路径在真实表上指定不存在的触发器，报告 `trigger "%s" for table "%s" does not exist`；随后可以创建并删除真实触发器。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `42704` |
| 条件名 | `undefined_object` |
| 状态 | `有效` |
| 已知存在于 | `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_UNDEFINED_OBJECT` |
| 别名 | `—` |

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

## 含义 {#meaning}

`42704` 表示未定义对象。`get_trigger_oid` 按已解析关系 OID 和触发器名称扫描 `pg_trigger`；当 `DROP TRIGGER` 要求对象而没有匹配行时，会发出 `ERROR`：`trigger "%s" for table "%s" does not exist`。选定路径在真实表上指定不存在的触发器，随后用创建并删除真实触发器验证修复生命周期。

对象类型决定查找方式和报文：固定分支包括类型名解析失败的 `type "%s" does not exist`、角色查找失败的 `role "%s" does not exist`、按关系 OID 扫描约束失败的 `constraint "%s" for table "%s" does not exist`，以及在访问方法下解析限定名或 search_path 中 opclass 失败的 `operator class "%s" does not exist for access method "%s"`。选定路径更具体：`get_trigger_oid` 按关系 OID 和触发器名查 `pg_trigger`，当前表没有匹配行时发出 `trigger "%s" for table "%s" does not exist`；随后案例只为验证修复生命周期而创建并删除真实触发器。

## 诊断 {#diagnosis}

先按主报文分类。对于选定触发器分支，检查 DDL 实际解析到的带 schema 关系、准确触发器名称（包括带引号大小写）和迁移顺序；触发器可能存在于另一张表，但由于源码按关系 OID 和名称查找，在当前关系上仍不存在。对于类型或角色报文，检查准确限定名以及 type/role 目录；对于约束报文，检查关系 OID/名称组合和迁移顺序；对于 opclass 报文，检查访问方法以及 opclass 查找使用的 schema/search_path。schema 缺失或未限定关系不存在属于另一类 namespace/未定义关系诊断，权限失败则是 42501。未找到对象的 `ERROR` 后选定自动提交会话仍为 `IDLE`；显式 `BEGIN` 中它会让事务进入 `INERROR`，直到 `ROLLBACK` 或回滚到合适保存点。它不同于 dblink 句柄错误 08003 和预备语句名称错误 26000。

## 处理 {#response}

按报文指出的对象类型修复：改正限定名或 search_path，按依赖顺序应用前置迁移，或在对应 owner 的迁移中创建/重命名预期的 type、role、constraint 或 operator class。仅对选定触发器案例，才应显式操作目标关系，核对 owner、时机/事件、行级或语句级定义及函数，并在迁移要求时删除准确触发器。如果对象本来就是可选的，应有意识地选择幂等迁移策略；不要用 `CASCADE`、无关对象或通用的“先创建再删除”作为修复。显式事务报错后，先回滚事务或合适保存点，再重试。

## 报文 {#messages}

选定的 `get_trigger_oid` 分支以明确的 `ERROR` 发出主报文 `trigger "%s" for table "%s" does not exist`；触发器名和表名都是动态值。其他固定未定义对象分支发出 `type "%s" does not exist`、`role "%s" does not exist`、`constraint "%s" for table "%s" does not exist` 或 `operator class "%s" does not exist for access method "%s"`。只有客户端异常而没有对应对象类型的服务器 SQLSTATE 和主报文时，不能据此识别 `42704`。

## 代表案例 {#case}

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

本页使用与运行器注册表相同的语句。执行时，`syntax_schema`、`syntax_role` 等生成名称会替换为一次性实例中的实际值。

```sql
CREATE TABLE syntax_schema.trigger_table (id integer);
DROP TRIGGER missing_trigger ON syntax_schema.trigger_table;
CREATE FUNCTION syntax_schema.trigger_function() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RETURN NEW; END $$;
CREATE TRIGGER valid_trigger BEFORE INSERT ON syntax_schema.trigger_table FOR EACH ROW EXECUTE PROCEDURE syntax_schema.trigger_function();
DROP TRIGGER valid_trigger ON syntax_schema.trigger_table;
SELECT count(*) FROM pg_trigger WHERE tgrelid = 'syntax_schema.trigger_table'::regclass AND NOT tgisinternal;
```

<!-- END SQLSTATE SNIPPET -->

选定的 18.6 运行记录结构化诊断并通过修复断言；10.21 运行通过同一案例的具体检查。可下载的案例和证据投影分别是 [`42704 案例 JSON`](../../data/cases/42704.json) 和 [`作者证据`](../../data/evidence/42704.json)。运行器清单为 `verify/cases/42704/cases.json`，页面 SQL 会与共享注册表核对。

## 版本 {#versions}

选定的自然运行范围是 PostgreSQL 18.6 与 10.21，不能据此推断所有中间版本的行为。

## 相关 {#related}

- [`42703` — 未定义列](../42703/)
- [`26000` — 相关条件](../26000/)

## 来源 {#sources}

- `src.errcodes.18.6` — fixed `errcodes.txt` definition at commit `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt)).
- `src.missing-trigger.18.6` — `src/backend/commands/trigger.c` at `REL_18_6` commit `724edf9bde9d356724ad384a2e196edc3c9f80f7`; fixed blob SHA-256 `0a539af85b0de1a04779f92202e7bfc77d85ae6da1747ea32527c67f39084fbd` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/trigger.c#L1406-L1409)).
- `src.missing-trigger.10.23` — `src/backend/commands/trigger.c` at `REL_10_23` commit `02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4`; fixed blob SHA-256 `dac7cdcbe2df1a1bbc77daa23e808b0c81ba8891c9895f10e8b270a15316e225` ([source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/commands/trigger.c#L1383-L1386)).
- `src.undefined-type.18.6` / `src.undefined-type.10.23` — fixed type-name lookup branches; blob SHA-256 `fe4670d2401141761096077c6495dd1b7d6a0baf33c9b903f25baee2f88ffd1e` / `729d30e50cea059ccfe13491fdc5f997ff98c227795693bf166a163925beb663` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/objectaddress.c#L1618-L1624), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/catalog/objectaddress.c#L1493-L1509)).
- `src.undefined-role.18.6` / `src.undefined-role.10.23` — fixed `DROP ROLE` lookup branches; blob SHA-256 `aa8769a2577fff287301d6c82169262cca328515ae940d5a2be4b3e8c21617ed` / `9fc68a5a18c4bb5388cc817d2f3f2fcdc64f2752eaa429f78f54b0b443fb59ec` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/user.c#L1129-L1135), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/commands/user.c#L1017-L1023)).
- `src.undefined-constraint.18.6` / `src.undefined-constraint.10.23` — fixed relation-constraint lookup branches; blob SHA-256 `0aa324acd355da955f8eb6cec17f1a0138277a8bebd2c6e999cd2a603d3bfa01` / `c90dff2d1d863e6b43102d762cec6e08b6c4ba40458045b525a14b49865d8a65` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/pg_constraint.c#L1218-L1238), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/catalog/pg_constraint.c#L781-L801)).
- `src.undefined-opclass.18.6` / `src.undefined-opclass.10.23` — fixed access-method/opclass lookup branches; blob SHA-256 `f28ac0580c805553724dc623dd4e20f32de1a84db637e6ac3c6e3d296bd2fae5` / `85c646706908d13dc449bcffa6690d6ead8d326498051fef6b08f817347fa947` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/opclasscmds.c#L145-L207), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/commands/opclasscmds.c#L145-L207)).
- `src.calls.REL_18_6` / `src.calls.REL_10_23` — fixed call scans, SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf` / `00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c`.
