域名 AXUM.RS 将于 2025 年 10 月到期。我们无意再对其进行续费,如果你有意接续这个域名,请与我们取得联系。
  • AXUM.RS 现仅需人民币 3000 元(大写:叁仟元整。接受适度议价
  • 按照行业规则,AXUM.RS 到期后,大概率会进入长时间的赎回期,该期间内,如果你想拥有该域名,将要付出高额的费用
  • 我们已启用 AXUM.EU.ORG 域名,并将持续运营
  • 仅接受微信或支付宝交易
如果你对 AXUM.RS 有兴趣,请和我们进行联系:

游标

本章我们将讨论 PL/pgSQL 的游标以及如何使用它们逐行处理结果集。

声明游标

要使用游标,必须先对其进行声明。

PostgreSQL 提供了 REFCURSOR 的特殊类型用来声明游标。语法如下:

declare 游标名 refcursor;

还可以使用以下语法声明绑定到查询的游标:

游标名 [ [no] scroll ] cursor [(参数列表)] for 查询;
  • SCROLL:游标可以向后滚动;NO SCROLL:游标无法向后滚动
  • 参数列表:定义查询参数(参数名 数据类型),多个参数以逗号分隔。当游标打开时,这些参数将被具体值替换。
  • 查询:可以是任何有效的 SELECT 语句

以下示例演示了如何声明游标:

declare
    cur_films  cursor for 
		select * 
		from film;
    cur_films2 cursor (year integer) for 
		select * 
		from film 
		where release_year = year;

打开游标

游标必须先打开才能用于查询,PostgreSQL 提供了打开绑定和未绑定游标的方法。

打开未绑定游标

OPEN 未绑定游标变量 [ [ NO ] SCROLL ] FOR query;

由于未绑定游标变量在声明时没有和任何查询进行绑定,因此在打开它的时候需要指定查询,如下例:

open my_cursor for 
	select * from city 
	where country = p_country;

PostgreSQL 还允许打开游标时,将其绑定到动态查询上,语法如下:

open 未绑定游标变量[ [ no ] scroll ] 
for execute 查询字符串 [using 表达式 [, ... ] ];

比如:

query := 'select * from city order by $1';

open cur_city for execute query using sort_field;

打开绑定游标

因为绑定游标在声明时已经和查询做了绑定,所以打开它的时候,只需要将必要的参数传递给查询即可,语法如下:

open 游标变量[ (参数1:=值1,参数2:=值2,...)];

比如打开上面声明的 cur_filmscur_films2游标:

open cur_films;
open cur_films2(year:=2005);

使用游标

打开游标后,可以使用 FETCHMOVEUPDATEDELETE语句来进行操作。

获取下一行

语法:

fetch [ 方向 { from | in } ] 游标变量 
into 目标变量;
  • FETCH 语句从游标中获取下一行,并赋值给 目标变量。它可以是一条记录、行变量或者以逗号分隔的变量列表。如果找不到更多多行,则将 目标变量 设置为 NULL
  • 方向可能的取值:
    • NEXT:下一行(默认值)
    • LAST:最后一行
    • PRIOR:上一行
    • FIRST:第一行
    • ABSOLUTE 数值:绝对计数
    • RELATIVE 数值:相对计数
    • FORWARD:向前
    • BACKWARD:后退
    • FORWARDBACKWARD仅适用于 SCROLL 声明的游标
  • NEXT:下一行(默认值)
  • LAST:最后一行
  • PRIOR:上一行
  • FIRST:第一行
  • ABSOLUTE 数值:绝对计数
  • RELATIVE 数值:相对计数
  • FORWARD:向前
  • BACKWARD:后退
  • FORWARDBACKWARD仅适用于 SCROLL 声明的游标

示例:

fetch cur_films into row_film;
fetch last from row_film into title, release_year;

移动游标

move [ 方向 { from | in } ] 游标变量;

方向 的取值和 FETCH 一样。

举例:

move cur_films2;
move last from cur_films;
move relative -1 from cur_films;
move forward 3 from cur_films;

删除或更新行

游标定位后,可以使用 DELETE WHERE CURRENT OFUPDATE WHERE CURRENT OF 来删除或更新游标标识的行,语法如下:

update 表名 
set 字段 = 值, ... 
where current of 游标变量;

delete from 表名 
where current of 游标变量;
update film 
set release_year = p_year 
where current of cur_films;

关闭游标

CLOSE 语句释放资源和游标变量,以允许再次使用 OPEN 语句打开它。

close 游标变量;

示例:将游标封装到函数中

以下 get_film_titles(integer) 函数接受代表电影发行年份的参数。在函数内部,我们查询发行年份等于传递给函数的发行年份的所有电影。我们使用游标循环遍历行,并将标题包含 ful 单词的电影的标题和发行年份连接起来。

要查看完整内容,请先登录