选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

文档 / SQL 状态码 / Class 34 游标名称无效

34000 invalid_cursor_name

游标名称无效

ERROR 已实测 详解 实测通过

类别
Class 34 游标名称无效
严重等级
ERROR
条件名
invalid_cursor_name
宏名称
ERRCODE_INVALID_CURSOR_NAME ERRCODE_UNDEFINED_CURSOR ERRCODE_UNDEFINED_CURSOR
启用版本
7.4
状态
活跃

版本覆盖

速览

34000 表示当前后端会话无法解析游标或 portal 名称。已经关闭的游标、在另一个连接池会话声明的游标、或事务结束后消失的游标,都不是“游标存在但位置错误”(24000)。

含义

执行器的 portal 路径在 FETCH 找不到命名 portal 时报告 cursor "%s" does not exist。游标属于后端会话;普通游标还受事务生命周期约束,除非明确声明合适的 hold 选项。因此连接池必须在预期事务边界内保持声明和使用都在同一连接。

诊断

记录 SQLSTATE、动态游标名称、后端 PID 和事务状态。检查应用是否提前 CLOSE、发生隐式提交、把连接归还池中,或已经换到另一会话。同一后端上的 pg_cursors 和会话身份可以帮助诊断;新连接不能查看或抓取旧连接拥有的游标。

处理

显式事务中的 FETCH 失败后,先回滚再发后续命令。在同一会话重新声明游标;如果工作必须跨连接池 checkout,就改为物化键或结果。只有确实需要提交后继续读取时才使用 holdable cursor;它不会让游标跨会话可用。

可复现案例

在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。

cursor_lifecycle_recovery PG 10 / 18 有 SQL

前置条件

  • A runner-owned disposable target is provisioned.

触发

Declare and close a named cursor, attempt to use it again, then recreate it in a new explicit transaction on the same session.

断言

  • SQLSTATE is 34000
  • The missing cursor diagnostic is preserved
  • The failed block recovers through ROLLBACK
  • A recreated cursor can FETCH and COMMIT

处置

Keep cursor use on the declaring backend session and respect its transaction lifetime; after an error, roll back before recreating it.

清理

Drop the case schema with an owner connection.

报文

选定核心路径使用 cursor "%s" does not exist;协议和 PL/pgSQL 路径可能使用 portal "%s" 或相同的 cursor 措辞。名称是动态值,应使用 SQLSTATE 和诊断字段,而不是跨版本、跨调用者比较完整报文。

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 cursor "%s" does not exist

来源:src/backend/commands/portalcmds.c @ REL_18_6

适用范围:The portal protocol path uses portal "%s" does not exist.

代表案例

共享 registry verify/cases/34000/snippets.json(SHA-256 ad5b519e8ca30fd2636b1d0bace32dc18558cccc7b9d360081c27b12a1405f08)先声明并关闭游标,验证缺失 FETCH,再在同一会话回滚并重新声明。见公开案例导出结构化证据

BEGIN;
DECLARE cursor_name CURSOR FOR SELECT 1;
CLOSE cursor_name;
FETCH cursor_name;
ROLLBACK;
BEGIN;
DECLARE cursor_name CURSOR FOR SELECT 1;
FETCH cursor_name;
CLOSE cursor_name;
COMMIT;

运行器会替换唯一游标名。第一次 FETCH 特意放在 CLOSE 之后;第二次在新的 BEGIN 和声明之后执行,成功返回数据,证明是生命周期修复而非客户端模拟。

选定案例在 PostgreSQL 18.6 和 10.21 关闭命名游标后执行 FETCH,观察到 34000。失败块进入 INERROR;回滚后重新声明、抓取、关闭并提交,连接回到 IDLE

版本

锁定目录在正式快照中都记录了该条件。18.6 和 10.23 源码扫描都包含 portal、PL/pgSQL 路径;选定运行在 18.6 与 10.21 观察到相同 SQLSTATE,但源码行和调用者措辞可能变化。

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

  • 34000 is the invalid_cursor_name condition in Class 34 and shares the undefined-cursor alias.

    核实方式Read the fixed errcodes.txt row and macro mapping.

    不覆盖The same SQLSTATE covers several cursor/portal-facing paths.

    来源src/backend/utils/errcodes.txt

  • PerformPortalFetch emits cursor "%s" does not exist when the named portal is absent.

    核实方式Trace ERRCODE_UNDEFINED_CURSOR in portalcmds.c.

    不覆盖Other callers use portal or cursor wording; the name is dynamic.

    来源src/backend/commands/portalcmds.c · raw/calls/REL_18_6.jsonl

  • A named cursor belongs to its backend session and transaction lifecycle; closing it or losing its transaction makes a later FETCH invalid.

    核实方式Compare DECLARE cursor lifecycle with the explicit same-session registry case.

    不覆盖Holdable cursors and client-side cursor abstractions have additional rules.

    来源doc/src/sgml/ref/declare.sgml

  • The selected 34000 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries.

    核实方式Read the selected runner summaries and raw outputs tied to the shared snippet registry.

    不覆盖This covers the selected mechanism only, not all source callers or all driver/pool behavior.

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed cursor_lifecycle_recovery
pg10 10.21 (Debian 10.21-1.pgdg90+1) passed cursor_lifecycle_recovery

同类 SQL 状态码

状态码 条件名 宏名称 严重等级 版本
Class 34 游标名称无效 Invalid Cursor Name 1 个
34000 invalid_cursor_name ERRCODE_INVALID_CURSOR_NAME ERROR 7.4
会话中无法解析该游标或 portal 名称。 活跃