FETCH
FETCH — 使用游标从查询中检索行
大纲
FETCH [direction] [ FROM | IN ]cursor_name其中direction可以是以下之一: NEXT PRIOR FIRST LAST ABSOLUTEcountRELATIVEcountcountALL FORWARD FORWARDcountFORWARD ALL BACKWARD BACKWARDcountBACKWARD ALL
描述
FETCH 使用先前创建的游标检索行。
游标带有一个关联位置,FETCH 会使用该位置。游标位置可以位于查询结果的第一行之前、结果中的任意一行上,或者位于结果的最后一行之后。游标创建时位于第一行之前。提取若干行后,游标会定位在最近提取的那一行上。如果 FETCH
越过了可用行的末尾,那么游标会留在最后一行之后;如果是向后提取,则会留在第一行之前。FETCH ALL 或者
FETCH BACKWARD ALL 总是会让游标位于最后一行之后或第一行之前。
NEXT、PRIOR、FIRST、LAST、ABSOLUTE、RELATIVE
这些形式会在适当地移动游标后提取一行。如果不存在这样的行,则返回空结果,并根据情况将游标定位在第一行之前或最后一行之后。
使用 FORWARD 和 BACKWARD 的形式会在向前或向后的方向上提取指定数量的行,并将游标定位在最后返回的那一行上(如果 count 超过可用行数,则定位在所有行之后或之前)。
RELATIVE 0、FORWARD 0 以及
BACKWARD 0 都会请求提取当前行而不移动游标,也就是重新提取最近一次提取的行。除非游标位于第一行之前或最后一行之后,否则该操作都会成功;在这两种情况下,不会返回任何行。
注意
本页面描述的是 SQL 命令层面的游标用法。如果想要在 PL/pgSQL 函数中使用游标,规则会有所不同 — 见第 41.7.3 节。
参数
direction#direction定义提取方向以及要提取的行数。它可以是下列之一:NEXT#提取下一行。如果省略
direction,这将是默认值。PRIOR#提取前一行。
FIRST#提取查询的第一行(与
ABSOLUTE 1相同)。LAST#提取查询的最后一行(与
ABSOLUTE -1相同)。ABSOLUTE#count提取查询的第
count行;如果count为负,则提取从末尾算起的第abs(行。如果count)count超出范围,则定位在第一行之前或最后一行之后。特别地,ABSOLUTE 0会定位在第一行之前。RELATIVE#count提取后面的第
count行;如果count为负,则提取前面的第abs(行。count)RELATIVE 0会重新提取当前行(如果有)。count#提取接下来的
count行(与FORWARD相同)。countALL#提取所有剩余行(与
FORWARD ALL相同)。FORWARD#提取下一行(与
NEXT相同)。FORWARD#count提取接下来的
count行。FORWARD 0会重新提取当前行。FORWARD ALL#提取所有剩余行。
BACKWARD#提取前一行(与
PRIOR相同)。BACKWARD#count提取前面的
count行(反向扫描)。BACKWARD 0会重新提取当前行。BACKWARD ALL#提取之前的所有行(反向扫描)。
count#count是一个可带符号的整数常量,用于确定要提取的位置或行数。对于FORWARD和BACKWARD这两种情况,指定负的count等效于颠倒FORWARD和BACKWARD的方向。cursor_name#一个已打开游标的名称。
输出
成功完成时,FETCH 命令会返回如下形式的命令标签:
FETCH count
其中 count 是提取到的行数(可能为零)。注意,在 psql 中,命令标签实际上不会显示,因为 psql 会改为显示提取到的行。
注解
如果打算使用除 FETCH NEXT 或带正数计数的
FETCH FORWARD 之外的任何 FETCH
变体,则应当在声明游标时使用 SCROLL 选项。对于简单查询,PostgreSQL 允许从未使用 SCROLL
声明的游标向后提取,但最好不要依赖这种行为。如果游标声明为
NO SCROLL,则不允许向后提取。
ABSOLUTE 提取并不比通过相对移动到达目标行更快:无论如何,底层实现都必须遍历所有中间行。负值的绝对提取甚至更糟:必须先把查询读到末尾以找到最后一行,然后再从那里反向遍历。不过,回卷到查询起始处(如 FETCH ABSOLUTE 0)是很快的。
示例
下面的示例展示了如何使用游标遍历一个表:
BEGIN WORK; -- 建立一个游标: DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films; -- 从游标 liahona 中提取前 5 行: FETCH FORWARD 5 FROM liahona; code | title | did | date_prod | kind | len -------+-------------------------+-----+------------+----------+------- BL101 | The Third Man | 101 | 1949-12-23 | Drama | 01:44 BL102 | The African Queen | 101 | 1951-08-11 | Romantic | 01:43 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 P_302 | Becket | 103 | 1964-02-03 | Drama | 02:28 -- 提取前一行: FETCH PRIOR FROM liahona; code | title | did | date_prod | kind | len -------+---------+-----+------------+--------+------- P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 -- 关闭游标并结束事务: CLOSE liahona; COMMIT WORK;
兼容性
SQL 标准只为嵌入式 SQL 定义了 FETCH。这里描述的 FETCH 变体会像
SELECT 结果那样返回数据,而不是把数据放入主变量中。除此之外,FETCH 与 SQL 标准完全向上兼容。
涉及 FORWARD 和 BACKWARD 的
FETCH 形式,以及形式 FETCH 和 countFETCH
ALL(其中隐含了 FORWARD)都是
PostgreSQL 扩展。
SQL 标准只允许在游标名之前使用 FROM;允许使用
IN,或者将两者都完全省略,都是扩展。