postgresql 使用游标笔记
游标介绍:游标是一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务端的sql语句,或是批处理、存储过程、触发器中的数据处理请求。
游标的优点在于它允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力。缺点是处理大数据量时,效率低下,占用内存大。一般来说,能使用其他方式处理数据时,最好不要使用游标,除非是当你使用while循环,子查询,临时表,表变量,自建函数或其他方式都无法处理某种操作的时候,再考虑使用游标。
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。
PostgreSQL游标可以封装查询并对其中每一行记录进行单独处理。当我们想对大量结果集进行分批处理时可以使用游标,因为一次性处理可能造成内存溢出。另外我们可以定义函数返回游标类型变量,这是函数返回大数据集的有效方式,函数调用者根据返回游标对结果进行处理。
游标使用顺序:声明游标 > 打开游标 > 使用游标 > 关闭游标 。
先展示一个游标的示例,以下get_film_titles(integer)函数接受代表电影发行年份的参数。在函数内部,我们查询所有发行年份等于传递给该函数的发行年份的电影。我们使用光标在各行之间循环,并连接标题和标题包含ful 单词的电影发行年份。
CREATE OR REPLACE FUNCTION get_film_titles(p_year INTEGER)
RETURNS text AS $$
-- 声明游标
DECLARE
titles TEXT DEFAULT '';
rec_film RECORD;
cur_films CURSOR(p_year INTEGER) FOR SELECT * FROM film WHERE release_year = p_year;
BEGIN
-- 打开游标
OPEN cur_films(p_year); LOOP
-- 获取记录放入film
FETCH cur_films INTO rec_film;
-- exit when no more row to fetch
EXIT WHEN NOT FOUND; -- 构建输出
IF rec_film.title LIKE '%ful%' THEN
titles := titles || ',' || rec_film.title || ':' || rec_film.release_year;
END IF;
END LOOP; -- 关闭游标
CLOSE cur_films; RETURN titles;
END; $$ LANGUAGE plpgsql; SELECT get_film_titles(2006); --返回结果 ,Grosse Wonderful:2006,Day Unfaithful:2006,Reap Unfaithful:2006,Unfaithful Kill:2006,Wonderful Drop:2006
一、声明游标
PostgreSQL声明游标有两种方法,一种是使用特殊类型REFCURSOR声明游标变量,另一种是声明和查询绑定使用。
-- 第一种方式
DECLARE my_cursor REFCURSOR; -- 第二种方式
cursor_name [ [NO] SCROLL ] CURSOR [( name datatype, name data type, ...)] FOR query;
首先,为光标指定一个变量名。接着指定是否可以使用向后滚动光标SCROLL,如果使用NO SCROLL,则光标无法向后滚动。然后,在CURSOR关键字后面加上一个逗号分隔的参数列表(name datatype),这些参数定义了查询的参数。打开游标时,这些参数将被值替换。最后,可以在FOR关键字之后指定查询,使用任何有效的SELECT语句。
示例:
DECLARE
cur_films CURSOR FOR SELECT * FROM film;
cur_films2 CURSOR (year integer) FOR SELECT * FROM film WHERE release_year = year; -- 该cur_films 包含film表所有行。
-- 本cur_films2 包含film表特定发行年份的记录。
二、打开游标
PostgreSQL提供了用于打开未绑定和绑定的游标的语法。
1.打开未绑定的游标
OPEN unbound_cursor_variable [ [ NO ] SCROLL ] FOR query;
-- 由于声明时未绑定的游标变量未绑定到任何查询,因此在打开它时必须指定查询。请参见以下示例:
OPEN my_cursor FOR SELECT * FROM city WHERE counter = p_country; -- PostgreSQL允许我们打开游标并将其绑定到动态查询。语法如下:
OPEN unbound_cursor_variable[ [ NO ] SCROLL ]
FOR EXECUTE query_string [USING expression [, ... ] ]; -- 在下面的示例中,我们构建一个动态查询,该动态查询根据一个sort_field参数对行进行排序,并打开执行该动态查询的游标。
query := 'SELECT * FROM city ORDER BY $1';
OPEN cur_city FOR EXECUTE query USING sort_field;
2.打开绑定的游标
因为绑定游标在声明时已经绑定到查询,所以当我们打开它时,只需要在必要时将参数传递给查询。
OPEN cursor_variable[ (name:=value,name:=value,...)];
-- 在下面的示例中,我们打开了绑定游标,cur_films并cur_films2在上面声明了该游标:
OPEN cur_films;
OPEN cur_films2(year:=2005);
三、使用游标
使用FETCH,MOVE,UPDATE或DELETE语句操作游标。
1.获取下一行
FETCH [ direction { FROM | IN } ] cursor_variable INTO target_variable;
该FETCH语句从游标中获取下一行,并为其分配一个target_variable,它可以是记录,行变量或逗号分隔的变量列表。如果找不到更多行,则将target_variable其设置为NULL(s)。
如果不显示指定方向,方向缺省为NEXT。可以有下面值:
- NEXT
- LAST
- PRIOR
- FIRST
- ABSOLUTE count
- RELATIVE count
- FORWARD
- BACKWARD
请注意,FORWARD和BACKWARD方向仅适用于用SCROLL option 声明的游标。
示例:
FETCH cur_films INTO row_film;
FETCH LAST FROM row_film INTO title, release_year;
2.移动光标
MOVE [ direction { FROM | IN } ] cursor_variable;
如果只想移动游标而不检索任何行,则使用该MOVE语句。方向接受与FETCH语句相同的值。
MOVE cur_films2;
MOVE LAST FROM cur_films;
MOVE RELATIVE -1 FROM cur_films;
MOVE FORWARD 3 FROM cur_films;
3.删除和更新行
使用DELETE WHERE CURRENT OF或UPDATE WHERE CURRENT OF语句删除或更新游标标识的行。
UPDATE table_name
SET column = value, ...
WHERE CURRENT OF cursor_variable; DELETE FROM table_name
WHERE CURRENT OF cursor_variable;
示例:
UPDATE film SET release_year = p_year
WHERE CURRENT OF cur_films;
四、关闭游标
使用CLOSE关闭打开的游标,CLOSE语句释放资源或释放游标变量,以允许使用该OPEN语句再次打开它。
CLOSE cursor_variable;
五、其他
-- 临时表返回结果例子
BEGIN;
DO $$
DECLARE
temp_geometry st_geometry;
geometry_record RECORD;
cur_geometry CURSOR FOR SELECT shape as shape FROM mainbasin;
BEGIN
OPEN cur_geometry;
FETCH cur_geometry INTO temp_geometry;
LOOP
FETCH cur_geometry INTO geometry_record;
EXIT WHEN NOT FOUND;
temp_geometry := st_union(temp_geometry,geometry_record.shape);
END LOOP;
CLOSE cur_geometry; DROP TABLE IF EXISTS temp_table;
CREATE TEMP TABLE temp_table AS
SELECT st_envelope(temp_geometry) shape;
END;
$$;
COMMIT;
SELECT st_astext(shape) FROM temp_table;
参考:https://www.postgresqltutorial.com/plpgsql-cursor/
postgresql 使用游标笔记的更多相关文章
- Bandwidthd+Postgresql数据库配置笔记
Bandwidthd+Postgresql数据库配置笔记 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/zjianbo/article/detai ...
- 转PostgreSQL 用游标优化的一个例子
一位PG社区的朋友提到的一个应用场景,目前遇到性能问题. 数据结构大概是这样的,包含一个主键,一个数组,一个时间,其他字段. 请求分析: 有检索需求,比较频繁.查找数组中包含某些元素的记录,并按时间排 ...
- Mysql与PostgreSql数据库学习笔记---打酱油的日子
mysql 从最基础的数据引擎,到进程结构,都不能支持数据版本.导致其职能阻塞“并发”,不支持最基本的事务,innodb达不到基本事务要求,任何写数据,都导致整个表锁住.充其量只能算是一个玩具,或者说 ...
- oracle 游标笔记
declare v_x number; v_y number; v_geo clob; cursor cur is select c_x, c_y from t_map_data where c_ty ...
- 基于Jmeter的PostgreSQL空间性能测试笔记
这是很早之前做过的一个测试,最近在整理postgresql测试相关的资料,所以也把它拿出来了与大家分享. 首先解释一下所谓的PostgreSQL空间性能,主要是基于postgis的空间数据导入性能,详 ...
- PostgreSQL函数(存储过程)----笔记
PostgreSQL 函数也称为 PostgreSQL 存储过程. PostgreSQL 函数或存储过程是存储在数据库服务器上并可以使用SQL界面调用的一组SQL和过程语句(声明,分配,循环,控制流程 ...
- postgresql spi开发笔记
#include "postgres.h" #include "fmgr.h" #include <string.h> #ifdef PG_MODU ...
- PostgreSQL内核学习笔记四(SQL引擎)
PostgreSQL实现了SQL Standard2011的大部分内容,SQL处理是数据库中非常复杂的一部分内容. 本文简要介绍了SQL处理的相关内容. 简要介绍 SQL文的处理分为以下几个部分: P ...
- PostgreSQL内核学习笔记十一(索引)
Index Scan涉及到两部分的内容Heap Only Tuple和index-only-scan. 什么是Heap Only Tuple(HOT)? 例如:Update a Row Without ...
随机推荐
- Pod无法删除 强制删除pod
多次变更服务后,发现部分pod delete僵死无法删除,一直处于Terminating状态 kubectl delete pod $pod-name一直卡住或不生效 已经删除管理资源的情况下发现仍然 ...
- 【分布式】-- 基于Nacos、OpenFeign搭建的微服务抽奖系统后台小案例
1.项目介绍 最近入项目之前要求熟悉一下SpringCloud Nacos微服务基于Feign接口调用并整合Swagger2进行接口文档展示给前端,所以自己按照要求来编写并整合了一套基于SpringC ...
- ffmpeg安装之linux编译安装
转发自白狼栈:查看原文 关于ffmpeg的安装,有的人可能要折腾很久,甚至折腾一个礼拜,究其原因,基本都是编译安装惹的祸. 我们提供4种安装方式,最复杂的莫过于centos7上的编译安装. ffmpe ...
- 基于 element-plus 封装一个依赖 json 动态渲染的查询控件
前情回顾 基于 el-form 封装一个依赖 json 动态渲染的表单控件 Vue3 封装第三方组件(一)做一个合格的传声筒 功能 使用 vue3 + element-plus 封装了一个查询控件,专 ...
- GO学习-(30) Go语言操作kafka
go操作kafka Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展等特点.本文介绍了如何使用Go语言发送和接收 ...
- Python+Selenium - 一个元素有两个标签时:一个用于显示,一个用于底层
如下图,这种一个元素由两个标签控制的,用js改值时需要两个标签的属性值都改 改值代码 js_code = 'a = document.getElementById("lostdate&quo ...
- 操作系统-gcc编译器驱动程序
gcc编译器驱动程序,读取x.c文件,翻译成可执行目标文件x 1.预处理阶段 预处理器(cpp)将x.c(源程序,文本文件)中的#等直接插入程序文本中,成为另一个c程序x.i(文本文件) 2.编译阶段 ...
- XML文件存在中文注释报错问题( 3 字节的 UTF-8 序列的字节 3 无效)
今天在做mybatis项目的时候,给映射文件添加了中文注释后,程序就报错.把中文注释删除后,程序又可以正常执行.解决方法在下文提到. 我的xml映射文件如下: <?xml version=&qu ...
- PTA7~9题目集总结与归纳
前言: 总结三次题目集的知识点.题量.难度等情况. 目录: 题目集7(7-1).(7-2)两道题目的递进式设计分析总结 题目集8和题目集9两道ATM机仿真题目的设计思路分析总结 一. 题目集7(7-1 ...
- NOIP模拟测试28「阴阳·虎·山洞」
写这几个题解我觉得我就像在按照官方题解抄一样 阴阳 题解 将题目中给的阴阳看作黑色和白色 首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减 类似这样 否则不满足这个条件 但合法染色方 ...