概述
使用DECLARE定义一个游标, 游标可以被用来在大型查询暂停时检索少量的行。游标被创建后,可以用FETCH从中取得行。
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。
游标使用
SQL命令级
postgres=# begin; --开启事务
BEGIN
postgres=# declare mycur cursor for select * from user_info;--打开游标
DECLARE CURSOR
postgres=# fetch first from mycur;--取第一行数据
userid | name | birthday | crt_time
--------+--------+------------+----------------------------
1 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.239366
(1 row)
postgres=# fetch next from mycur;--取下一行数据
userid | name | birthday | crt_time
--------+--------+------------+---------------------------
2 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.23952
(1 row)
postgres=# move last in mycur; --游标移动到行尾
MOVE 1
postgres=# close mycur;关闭游标
CLOSE CURSOR
postgres=# commit;提交
COMMIT
复制
PL/pgSQL函数内使用
postgres=# create function my_cur(refcursor) returns refcursor as $$
postgres$# begin
postgres$# open $1 for select * from user_info;
postgres$# return $1;
postgres$# end;
postgres$# $$language plpgsql;
CREATE FUNCTION
postgres=# begin;
BEGIN
postgres=# select my_cur('test');
my_cur
--------
test
(1 row)
postgres=# fetch first from test;
userid | name | birthday | crt_time
--------+--------+------------+----------------------------
1 | abcdef | 2015-08-10 | 2021-07-05 23:03:00.239366
(1 row)
复制
源码导读
src/backend/tcop/pquery.c
/*
* 对于Portals(客户端请求),有几种执行策略,具体取决于要执行什么查询。
* (注意:无论什么情况下,一个Portal只执行一个source-SQL查询,因此从用户的角度来看只产生一个结果。
* 但是,规则重写器可以将单个源查询扩展为零或多个实际查询。
*
* PORTAL_ONE_SELECT: 包含一个SELECT查询。
* 按需要的结果重复(递增)地运行执行器。
* 该策略还支持可持有游标(执行器结果可以在事务完成后转储到tuplestore中进行访问)。
*
* PORTAL_ONE_RETURNING: 包含一个带有RETURNING子句的INSERT/UPDATE/DELETE查询
(可能还包括由规则重写添加的辅助查询)。
* 在第一次执行时,运行Portal来完成并将主查询的结果转储到Portal的tuplestore中;
* 然后根据需要将结果返回给客户端。
* (我们不能支持半途中断的查询,因为AFTER触发器代码无法处理,
* 也因为不想冒执行所有辅助查询失败的风险)。
*
* PORTAL_ONE_MOD_WITH: 只包含一个SELECT查询,但它具有数据修改的CTEs。
* 这与PORTAL_ONE_RETURNING的情况相同,因为可能需要触发触发器。将来它的行为可能更像PORTAL_ONE_SELECT。
*
* PORTAL_UTIL_SELECT: 包含一个实用程序语句,该语句返回一个类似SELECT的结果(例如,EXPLAIN或SHOW)。
* 在第一次执行时,运行语句并将其结果转储到portal tuplestore;然后根据需要将结果返回给客户端。
*
* PORTAL_MULTI_QUERY: 除上述情况外的其他情况。
* 在这里,不支持部分执行:Portal的查询语句将在第一次调用时运行到完成。
*/
typedef enum PortalStrategy
{
PORTAL_ONE_SELECT,
PORTAL_ONE_RETURNING,
PORTAL_ONE_MOD_WITH,
PORTAL_UTIL_SELECT,
PORTAL_MULTI_QUERY
} PortalStrategy;
/* Features/options */
PortalStrategy strategy; /* 场景;see above */
int cursorOptions; /* DECLARE CURSOR选项位;DECLARE CURSOR option bits */
bool run_once; /* 是否只执行一次;portal will only be run once */
* 在这里,为持有的游标或PORTAL_ONE_RETURNING或PORTAL_UTIL_SELECT存储元组。
* (在事务结束后持有的游标不再具有任何活动执行器状态。)
Tuplestorestate *holdStore; /* 存储持有的游标信息;store for holdable cursors */
MemoryContext holdContext; /* 持有holdStore的内存上下文;memory containing holdStore */
//用于表示的数据,主要由pg_cursors系统视图使用
TimestampTz creation_time; /* portal定义的时间;time at which this portal was defined */
bool visible; /* 是否在pg_cursors中可见? include this portal in pg_cursors? */
* 游标可滚动,执行器需要支持REWIND和向后的扫描
if (portal->cursorOptions & CURSOR_OPT_SCROLL)
myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
else
myeflags = eflags;
复制
参考
https://www.postgresql.org/docs/current/sql-declare.html
http://postgres.cn/docs/12/sql-declare.html
文章转载自CP的PostgreSQL厨房,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
9.9 分高危漏洞,尽快升级到 pgAdmin 4 v9.2 进行修复
严少安
341次阅读
2025-04-11 10:43:23
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
326次阅读
2025-04-15 14:48:05
openHalo问世,全球首款基于PostgreSQL兼容MySQL协议的国产开源数据库
严少安
289次阅读
2025-04-07 12:14:29
外国CTO也感兴趣的开源数据库项目——openHalo
小满未满、
277次阅读
2025-04-21 16:58:09
postgresql+patroni+etcd高可用安装
necessary
157次阅读
2025-03-28 10:11:23
手把手教你在 openKylin 上部署 IvorySQL 4.4
严少安
149次阅读
2025-03-27 20:41:28
从 Oracle 到 PostgreSQL迁移成本评估揭秘
梧桐
148次阅读
2025-03-27 17:21:42
转发有奖 | PostgreSQL 16 PGCM高级认证课程直播班招生中!
墨天轮小教习
142次阅读
2025-04-14 15:58:34
墨天轮PostgreSQL认证证书快递已发(2025年3月批)
墨天轮小教习
125次阅读
2025-04-03 11:43:25
从Percona 发布Pro级产品得到的一些启发
库海无涯
122次阅读
2025-03-26 08:45:23