↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

Wiki / SQLSTATE

34000 — invalid_cursor_name(游标名称无效)

会话中无法解析该游标或 portal 名称。

英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。

当前阅读 PG 18·选择有来源记录的版本

aliases
未知
class name
Invalid Cursor Name
condition name
invalid_cursor_name
lang
en
sqlstate
34000

版本定义 PG 18

34000 — invalid_cursor_name(游标名称无效)

速览 {#at-a-glance}

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

含义 {#meaning}

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

诊断 {#diagnosis}

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

处理 {#response}

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

报文 {#messages}

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

代表案例 {#case}

共享 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。

版本 {#versions}

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

相关 {#related}

可对照24000 游标状态无效以及另一个会话资源错误26000 预备语句名称无效。

来源 {#sources}

  • src.errcodes.18.6(SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.portalcmds.18.6(SHA-256 e71c5bdb2da67771fb5f42f18b823e8af3ee6c31d5314e97a47ad18f7788bf35)
  • DECLARE 官方文档 · 本地调用扫描 src.calls.REL_18_6(SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)

比较版本

SQLSTATE 证据与已记录的运行版本

cases · cursor_lifecycle_recovery
{
  "assertions": [
    "SQLSTATE is 34000",
    "The missing cursor diagnostic is preserved",
    "The failed block recovers through ROLLBACK",
    "A recreated cursor can FETCH and COMMIT"
  ],
  "case_id": "cursor_lifecycle_recovery",
  "cleanup": "Drop the case schema with an owner connection.",
  "has_snippet": true,
  "position": 0,
  "preconditions": [
    "A runner-owned disposable target is provisioned."
  ],
  "repair": "Keep cursor use on the declaring backend session and respect its transaction lifetime; after an error, roll back before recreating it.",
  "trigger": "Declare and close a named cursor, attempt to use it again, then recreate it in a new explicit transaction on the same session.",
  "versions": [
    "10",
    "18"
  ]
}
claims · identity
{
  "claim_id": "identity",
  "limits": "The same SQLSTATE covers several cursor/portal-facing paths.",
  "method": "Read the fixed errcodes.txt row and macro mapping.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "34000 is the invalid_cursor_name condition in Class 34 and shares the undefined-cursor alias."
}
claims · portal-path
{
  "claim_id": "portal-path",
  "limits": "Other callers use portal or cursor wording; the name is dynamic.",
  "method": "Trace ERRCODE_UNDEFINED_CURSOR in portalcmds.c.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.portalcmds.18.6",
    "src.calls.REL_18_6"
  ],
  "statement": "PerformPortalFetch emits cursor \"%s\" does not exist when the named portal is absent."
}
claims · lifecycle
{
  "claim_id": "lifecycle",
  "limits": "Holdable cursors and client-side cursor abstractions have additional rules.",
  "method": "Compare DECLARE cursor lifecycle with the explicit same-session registry case.",
  "position": 2,
  "runtime": [],
  "sources": [
    "doc.declare.18.6"
  ],
  "statement": "A named cursor belongs to its backend session and transaction lifecycle; closing it or losing its transaction makes a later FETCH invalid."
}
claims · runtime
{
  "claim_id": "runtime",
  "limits": "This covers the selected mechanism only, not all source callers or all driver/pool behavior.",
  "method": "Read the selected runner summaries and raw outputs tied to the shared snippet registry.",
  "position": 3,
  "runtime": [],
  "sources": [
    "runtime.34000-batch34-20260909.latest",
    "runtime.34000-batch34-20260909.pg10"
  ],
  "statement": "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."
}
messages · message.cursor-missing
{
  "limits": "The portal protocol path uses portal \"%s\" does not exist.",
  "message_id": "message.cursor-missing",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.cursor-missing",
    "limits": "The portal protocol path uses portal \"%s\" does not exist.",
    "primary_template": "cursor \"%s\" does not exist",
    "severity_source": "ERROR",
    "sources": [
      "src.portalcmds.18.6"
    ],
    "sqlstate": "34000"
  },
  "severity": "ERROR",
  "sources": [
    "src.portalcmds.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "cursor \" \" does not exist",
      "position": 0,
      "role": "",
      "template": "cursor \"%s\" does not exist"
    }
  ]
}
runtimes · runtime.34000-batch34-20260909.latest · 18.6 (Homebrew) · passed
{
  "cases": [
    "cursor_lifecycle_recovery"
  ],
  "limits": "",
  "position": 0,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/34000/cases.json",
      "sha256": "72347c5c8f1ccfaa18aced582e9ff5bf0f968eff0547c9a8f6521ed7fa3adb47"
    },
    "cases": [
      "cursor_lifecycle_recovery"
    ],
    "id": "runtime.34000-batch34-20260909.latest",
    "observed": {
      "connection_autocommit": true,
      "primary": "cursor \"case_cursor_aa951a82\" does not exist",
      "repair": {
        "fetched_row": [
          1
        ]
      },
      "severity": "ERROR",
      "sqlstate": "34000",
      "statuses": {
        "after_error": "INERROR",
        "after_repair": "IDLE",
        "after_rollback": "IDLE"
      }
    },
    "raw": "verify/results/34000-batch34-20260909/latest/raw.jsonl",
    "raw_sha256": "91c68dc423bfd301219891f250d584678c5300e1376c9fb6d75731b169d5f560",
    "run_id": "34000-batch34-20260909",
    "server_version": "18.6 (Homebrew)",
    "snippet_registry": {
      "path": "verify/cases/34000/snippets.json",
      "sha256": "ad5b519e8ca30fd2636b1d0bace32dc18558cccc7b9d360081c27b12a1405f08"
    },
    "status": "passed",
    "summary": "verify/results/34000-batch34-20260909/latest/summary.json",
    "summary_sha256": "113822682213d49699a80ba97c2d3bad78a795790edfd32e7dbc362d16456e3e",
    "target": "latest"
  },
  "run_id": "34000-batch34-20260909",
  "runtime_id": "runtime.34000-batch34-20260909.latest",
  "server_version": "18.6 (Homebrew)",
  "status": "passed",
  "target": "latest"
}
runtimes · runtime.34000-batch34-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
  "cases": [
    "cursor_lifecycle_recovery"
  ],
  "limits": "",
  "position": 1,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/34000/cases.json",
      "sha256": "72347c5c8f1ccfaa18aced582e9ff5bf0f968eff0547c9a8f6521ed7fa3adb47"
    },
    "cases": [
      "cursor_lifecycle_recovery"
    ],
    "id": "runtime.34000-batch34-20260909.pg10",
    "observed": {
      "connection_autocommit": true,
      "primary": "cursor \"case_cursor_d0bb43e5\" does not exist",
      "repair": {
        "fetched_row": [
          1
        ]
      },
      "severity": "ERROR",
      "sqlstate": "34000",
      "statuses": {
        "after_error": "INERROR",
        "after_repair": "IDLE",
        "after_rollback": "IDLE"
      }
    },
    "raw": "verify/results/34000-batch34-20260909/pg10/raw.jsonl",
    "raw_sha256": "1089cf85363624dcf5430744047b9dfde4760d763ebe10d5ed148047f9bb7c5c",
    "run_id": "34000-batch34-20260909",
    "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
    "snippet_registry": {
      "path": "verify/cases/34000/snippets.json",
      "sha256": "ad5b519e8ca30fd2636b1d0bace32dc18558cccc7b9d360081c27b12a1405f08"
    },
    "status": "passed",
    "summary": "verify/results/34000-batch34-20260909/pg10/summary.json",
    "summary_sha256": "5c73ff2695864619e3771294e896ec2704bb4fae8e2b16d72aedf220063c2c6a",
    "target": "pg10"
  },
  "run_id": "34000-batch34-20260909",
  "runtime_id": "runtime.34000-batch34-20260909.pg10",
  "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
  "status": "passed",
  "target": "pg10"
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}
sources · src.calls.REL_18_6
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "",
  "path": "raw/calls/REL_18_6.jsonl",
  "position": 1,
  "sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
  "source_id": "src.calls.REL_18_6",
  "tag": "",
  "url": ""
}
sources · src.portalcmds.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/commands/portalcmds.c",
  "position": 2,
  "sha256": "e71c5bdb2da67771fb5f42f18b823e8af3ee6c31d5314e97a47ad18f7788bf35",
  "source_id": "src.portalcmds.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/portalcmds.c#L197-L199"
}
sources · doc.declare.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "https://www.postgresql.org/docs/18/sql-declare.html",
  "kind": "upstream_source",
  "location": "",
  "path": "doc/src/sgml/ref/declare.sgml",
  "position": 3,
  "sha256": "f1d72befb9a989aa32123560aea784a8bccfcb3d3930804a101d8245e5a3cc95",
  "source_id": "doc.declare.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/ref/declare.sgml"
}

来源引用

完整定义与证据 JSON

定义来源

center · PostgreSQL 18 · english-manuals:44fb2ceedd823afc8b65a568c17489e06450fe8b98537be62250077c30cf53b7

正文语言: zh-Hans · english-manuals:44fb2ceedd823afc8b65a568c17489e06450fe8b98537be62250077c30cf53b7