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-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.portalcmds.18.6(SHA-256e71c5bdb2da67771fb5f42f18b823e8af3ee6c31d5314e97a47ad18f7788bf35)DECLARE 官方文档· 本地调用扫描src.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)
比较版本
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"
}来源引用
定义来源
center · PostgreSQL 18 · english-manuals:44fb2ceedd823afc8b65a568c17489e06450fe8b98537be62250077c30cf53b7
正文语言: zh-Hans · english-manuals:44fb2ceedd823afc8b65a568c17489e06450fe8b98537be62250077c30cf53b7