尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
PostgreSQL 游标(cursor)实战:从 DECLARE 到 FETCH 的完整配置与验证
1. 为什么大批量数据处理绕不开 PostgreSQL 游标如果你写过SELECT * FROM big_table然后一次性把几十万行拉进内存大概率见过out of memory或者应用直接卡死。PostgreSQL 游标cursor就是解决这个问题的它把一个大结果集封装成一个可以逐行、分批读取的句柄你每次只取一部分内存占用可控。游标适合谁做数据迁移、批量对账、存储过程里逐行加工、分页导出报表的后端同学。它和普通LIMIT/OFFSET分页的区别在于游标在同一个事务里保持查询快照不会因为翻页期间数据变动导致漏行或重复行而且服务端只维护一个 portal不用每次重新执行查询。这篇我按DECLARE → OPEN → FETCH → CLOSE全流程走一遍给出可以直接复制到 psql 里跑的 SQL 骨架再补上存储过程里的绑定游标写法和几个我踩过的坑。你跟着敲一遍基本就能在自己的库上验证游标行为了。2. 前置准备连接环境与 TaoToken 接入游标本身是 PostgreSQL 原生能力不需要额外插件。但如果你是在做 AI 应用里的数据管道比如让模型去分析数据库里的批量记录通常需要一个统一的 API 入口来调用模型做逐行处理。我这边习惯用 TaoToken 做模型调用的统一网关把数据库取出的行喂给模型做分类、摘要、字段抽取。TaoToken 的定位是给开发者和智能硬件场景提供大模型 API 接入支持对话、编码、Agent 等调用方式。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 。如果你只是单纯练 PostgreSQL 游标这一节可以跳过如果要把游标逐行结果接到模型上就继续往下看。先拿到 API Key打开 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 创建一个 Key 并保存。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言的调用示例。想先在网页上试模型效果可以用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。注意API Key 只显示一次创建后立刻复制到环境变量里别硬编码进 SQL 或脚本。3. 可复制配置DECLARE / OPEN / FETCH / CLOSE 全流程3.1 建一张测试表并灌数据先在 psql 里准备数据后面所有示例都基于它CREATE TABLE film ( film_id serial PRIMARY KEY, title text, release_year integer ); INSERT INTO film (title, release_year) SELECT film_ || g, 2000 (g % 20) FROM generate_series(1, 100000) AS g; CREATE INDEX idx_film_year ON film (release_year);十万行足够体现游标分批读取的价值一次性SELECT *拉出来在客户端里也能明显感觉到内存差异。3.2 事务内声明并打开游标PostgreSQL 的游标默认只在事务内有效除非用WITH HOLD。所以标准姿势是BEGIN之后DECLAREBEGIN; DECLARE cur_films CURSOR FOR SELECT film_id, title, release_year FROM film WHERE release_year 2005; FETCH 5 FROM cur_films;DECLARE只是登记一个查询FETCH第一次执行时才真正开始取数。FETCH 5一次拿 5 行比逐行FETCH NEXT效率高很多这是批量处理的关键。3.3 带参数的绑定游标如果查询条件要动态传入用带参数的游标声明BEGIN; DECLARE cur_films_by_year CURSOR (y integer) FOR SELECT film_id, title FROM film WHERE release_year y; OPEN cur_films_by_year(2005); FETCH 10 FROM cur_films_by_year; CLOSE cur_films_by_year; COMMIT;参数在OPEN时传入游标声明里用(y integer)占位。这种写法在存储过程里特别常见因为函数参数可以直接透传。3.4 存储过程里的循环处理骨架真正逐行加工一般写在 plpgsql 函数里下面是一个完整可运行的例子统计某年份的电影标题拼接结果CREATE OR REPLACE FUNCTION collect_titles(p_year integer) RETURNS text AS $$ DECLARE rec record; result text : ; cur CURSOR (y integer) FOR SELECT title FROM film WHERE release_year y; BEGIN OPEN cur(p_year); LOOP FETCH cur INTO rec; EXIT WHEN NOT FOUND; result : result || rec.title || ;; END LOOP; CLOSE cur; RETURN result; END; $$ LANGUAGE plpgsql;调用验证SELECT left(collect_titles(2005), 120);EXIT WHEN NOT FOUND是循环终止条件FOUND在FETCH没取到行时会被置为 false。这个骨架你可以直接改成对每行做UPDATE、写日志表、或者调用外部接口。3.5 用 MOVE 跳过和定位有时候不需要返回行只想移动游标位置用MOVEBEGIN; DECLARE cur_all CURSOR FOR SELECT * FROM film ORDER BY film_id; MOVE FORWARD 1000 IN cur_all; FETCH 3 FROM cur_all; COMMIT;MOVE的方向关键字和FETCH一致NEXT、PRIOR、FIRST、LAST、ABSOLUTE n、RELATIVE n。想做分页导出时MOVE ABSOLUTE比反复OFFSET更省资源。4. 验证请求与成功结果4.1 在 psql 里逐步观察游标行为打开 psql按顺序执行观察每一步输出BEGIN; DECLARE cur_demo CURSOR FOR SELECT film_id, title FROM film WHERE release_year 2005 ORDER BY film_id; FETCH 3 FROM cur_demo;你会看到类似film_id | title ------------------ 5 | film_5 25 | film_25 45 | film_45 (3 rows)继续FETCH 3游标位置往后走返回接下来的三行。再执行MOVE BACKWARD 3后FETCH 1会回到之前的位置——前提是声明时用了SCROLL默认游标是NO SCROLL只能向前。4.2 验证游标是否真的省内存开两个 psql 会话一个执行BEGIN; DECLARE cur_big CURSOR FOR SELECT * FROM film; FETCH 100 FROM cur_big;另一个会话查后台内存SELECT pid, state, query FROM pg_stat_activity WHERE query LIKE %cur_big%;你会发现游标查询处于idle in transaction状态服务端只维护了 portal没有把十万行全部物化到内存。这就是游标分批处理的核心价值。4.3 把逐行结果接到模型调用如果你要把每行数据交给模型处理可以在应用层循环FETCH也可以把游标结果导出后批量调用。用 TaoToken 的 API 时请求体大致是这样curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [ {role: user, content: 把这条电影记录归类film_5, 2005} ] }把$TAOTOKEN_API_KEY换成你在 API Keys 页面创建的 Key。长期跑批量任务的话用 Coding Plan 更划算入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。如果你用的是 Claude Code 这类编码工具Anthropic 兼容接入方式见 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode_anthropicutm_campaignrewrite 。5. 本篇常见错排查5.1 cursor already in use在递归函数或嵌套调用里声明了绑定游标第二次进入时报这个错。原因是绑定游标的名字在会话内固定不能重复打开。解决办法是改用非绑定游标REFCURSOR在OPEN ... FOR时动态指定查询每次自动生成唯一 portal 名。5.2 cursor does not existDECLARE和FETCH不在同一个事务里。游标默认事务级COMMIT或ROLLBACK之后游标就没了。要么把操作放在同一个BEGIN...COMMIT块里要么声明时加WITH HOLDDECLARE cur_hold CURSOR WITH HOLD FOR SELECT * FROM film; COMMIT; FETCH 5 FROM cur_hold;WITH HOLD的游标在事务提交后仍然可用但会物化结果集大结果集慎用。5.3 FETCH 返回空但表里明明有数据检查游标声明时的WHERE条件是否和OPEN传参匹配。带参数游标最容易犯的错是声明用(y integer)OPEN时忘了传参或者传错类型。另外FETCH方向如果是BACKWARD而游标是NO SCROLL也会直接报错而不是返回空。5.4 游标循环里 UPDATE 报错WHERE CURRENT OF cursor_name只能更新游标当前指向的行且游标查询必须是简单的单表查询不能有JOIN、GROUP BY、DISTINCT。如果查询复杂改成先FETCH出主键再用主键UPDATE。5.5 长事务导致表膨胀游标持有期间事务一直开着会阻止 vacuum 回收死元组。批量处理十万行以上时建议分批COMMIT或者用WITH HOLD游标配合短事务。我踩过的坑就是跑一个百万行的游标循环忘了提交结果那张表膨胀了好几倍。6. 继续深入把游标接进你的数据管道游标本身不复杂难的是把它放进真实的数据处理链路里从库里分批取数、逐行加工、再写回或调用外部服务。如果你在做 AI 相关的数据管道把游标取出的行交给模型做结构化处理是很常见的模式。模型调用统一走 https://taotoken.net/api Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 管理接入细节看 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先验证模型对某批数据的处理效果直接在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 里贴几行试试确认 prompt 稳定了再写进游标循环。控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 可以看调用量和余额。最后留一个实用技巧游标循环里不要每行都RAISE NOTICE日志量大了会拖慢整个事务。要调试的话每 1000 行打一次或者写到临时表里最后统一查。
RELATED

相关推荐

WSL2 上 libtorch1.10.0-CPU 部署 PyTorch1.12.1 模型:TaoToken 统一 Key 配置与推理验证

WSL2 上 libtorch1.10.0-CPU 部署 PyTorch1.12.1 模型:TaoToken 统一 Key 配置与推理验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/27 19:55:01
鄂州网站建设企业推广避坑指南:5个关键注意事项

鄂州网站建设企业推广避坑指南:5个关键注意事项

鄂州网站建设企业推广避坑指南:5个关键注意事项 域名解析乱跳,服务器配置报错,SSL证书还没生效流量就断了。做鄂州网站建设企业推广,最头疼的往往不是代码写不出来,而是这些底层基础设施搞不懂,导致推广费打水漂。很多本地老板找团队做站,最后发现…

📅 2026/9/27 19:50:01
Windsurf 只有 160 人,OpenAI 却要出 30 亿:CEO 说,我们不是写代码,是决定写不写——用 TaoToken 统一 Key 打通 IDE 配置

Windsurf 只有 160 人,OpenAI 却要出 30 亿:CEO 说,我们不是写代码,是决定写不写——用 TaoToken 统一 Key 打通 IDE 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/27 19:50:01
MORE NEWS

更多资讯

📰

洗碗机水泵EMC整改实战:高集成驱动方案如何压低超标噪声

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

江门中企动力网站安全避坑指南5招搞定

江门中企动力网站安全避坑指南5招搞定 备案流程一头雾水,刚把域名解析好,网站突然打不开?别慌,这往往不是备案没下来,而是安全配置出了岔子。很多江门中企动力的客户在上线初期,因为忽视基础安全设置,导致网站被挂马、数据泄露,甚至被搜索引擎降权。…

📰

TI在线滤波器设计工具实战:从参数计算到电路调试全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

AI 写长篇别靠玄学:我用 codebubby + Cursor 把《一纸洛阳》写到50章不崩的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

CAN总线错误帧排查实战:从底层逻辑到ZCANPRO抓包定位

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Claude Code 功能介绍与安装教程:TaoToken 统一 Key 接入 VS Code 配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬