文档 / SQL 状态码 / Class 24 游标状态无效
24000 invalid_cursor_state
游标状态无效
ERROR 已实测 参考 实测通过
- 条件名
invalid_cursor_state- 宏名称
ERRCODE_INVALID_CURSOR_STATE- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
24000 表示游标或 portal 状态不满足当前操作。本案例声明了有效游标,却在 FETCH 定位前执行 WHERE CURRENT OF,因而报“游标未定位到行”。
含义
WHERE CURRENT OF 要求游标来自可更新查询,并已通过 FETCH 选中当前行;声明本身不会定位。其他非 SELECT、已保持、不可更新或缺少 FOR UPDATE/SHARE 引用的游标也有不同 24000 模板。
诊断
记录游标名和操作,检查声明、事务生命周期、FETCH 方向及可更新性。显式事务错误后本案例为 INERROR,回滚后回到 IDLE;本案例用主键直接更新修复,未测试重新 DECLARE/FETCH。
处理
先 FETCH 定位再使用 CURRENT OF,或者使用确定性的键更新。保持游标和事务生命周期显式,失败事务先回滚。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
current_of_before_fetch PG 10 / 18 有 SQL
前置条件
- A cursor is declared for a SELECT ... FOR UPDATE
- The cursor has not fetched a row
触发
Use WHERE CURRENT OF before the cursor is positioned on a row.
断言
- SQLSTATE is 24000
- The connection recovers after rollback
- A direct update succeeds afterward
处置
Fetch or otherwise position the cursor before CURRENT OF, or use a key-based update whose concurrency semantics are explicit.
清理
Drop the case schema with an owner connection.
实测诊断
18.6 (Homebrew) / latest:SQLSTATE 24000;primary cursor "item_cursor" is not positioned on a row;after_error INERROR;after_rollback IDLE。
10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 24000;primary cursor "item_cursor" is not positioned on a row;after_error INERROR;after_rollback IDLE。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
cursor "%s" is not positioned on a row
来源:src/backend/executor/execCurrent.c @ REL_18_6
适用范围:The same template is also used by another CURRENT OF path; the cursor name is substituted at runtime.
代表案例
运行器从 verify/cases/24000/snippets.json(SHA-256 cafca57825378362df0527384614bf658bf86cd3101e1eb520ea0641819f2789)读取下列片段,并为临时 schema 替换表名;完整 setup、断言与清理见 案例导出。
-- create
CREATE TABLE items(id integer PRIMARY KEY, note text NOT NULL);
-- seed
INSERT INTO items VALUES (1, 'seed');
-- begin
BEGIN;
-- declare
DECLARE item_cursor CURSOR FOR SELECT id FROM items FOR UPDATE;
-- trigger
UPDATE items SET note = 'bad' WHERE CURRENT OF item_cursor;
-- rollback
ROLLBACK;
-- repair
UPDATE items SET note = 'repaired' WHERE id = 1;
-- verify
SELECT id, note FROM items;
本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自上述共享 registry;结构化证据 · 案例导出。
作者证据 ID:identity, current-of, runtime。选定运行记录:runtime.24000-batch1-latest2-20260909.latest, runtime.24000-batch1-pg10-20260909.pg10。
版本与边界
锁定目录在 7.4 已观察到该条件,并在列出的正式快照中均存在。选定运行覆盖 18.6 与 10.21 的 FETCH 前 CURRENT OF 路径;其他游标状态需要独立案例。
来源
- 上游源码 doc/src/sgml/ref/declare.sgml 第 275–285 行
- 上游源码 doc/src/sgml/ref/update.sgml 第 203–211 行
- 上游源码 src/backend/utils/errcodes.txt
- 上游源码 src/backend/executor/execCurrent.c 第 135–138 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
24000 is invalid_cursor_state in Class 24.
-
UPDATE or DELETE ... WHERE CURRENT OF requires a positioned, updatable cursor row; before FETCH the executor reports 24000.
-
The selected explicit transaction case returned 24000 before FETCH, entered INERROR, recovered after ROLLBACK, and then directly repaired the row on PG18.6 and PG10.21.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | current_of_before_fetch |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | current_of_before_fetch |
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| 24000 | invalid_cursor_state | ERRCODE_INVALID_CURSOR_STATE |
ERROR | 7.4 |
| 游标或 portal 状态不满足当前操作要求。 | 活跃 | |||