FETCH — 使用游标从查询中检索行
FETCH [direction
[ FROM | IN ] ]cursor_name
其中direction
可以为空或者以下之一: NEXT PRIOR FIRST LAST ABSOLUTEcount
RELATIVEcount
count
ALL FORWARD FORWARDcount
FORWARD ALL BACKWARD BACKWARDcount
BACKWARD 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函数中使用游标,规则会有所不同 — 请见Section 43.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
相同)。
count
ALL
取出所有剩余的行(和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
he BACKWARD
的意义。
cursor_name
一个已打开游标的名称。
如果成功完成,FETCH
命令返回一个下面形式的命令标签:
FETCH count
count
是取得的行数(可能
为零)。注意在ltsql中,命令标签将不会实际显示,
因为ltsql会显示被取得的行。
如果想要使用FETCH
的任意变体而不使用带有正计数的
FETCH NEXT
或者FETCH FORWARD
,
应该用SCROLL
声明游标。对于简单查询,
LightDB将允许从不带
SCROLL
的游标中反向取得行,但最好不要依赖这种行为。
如果游标被声明为带有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 标准只定义FETCH
在嵌入式 SQL 中使用。
这里描述的FETCH
变体返回数据时就好像数据是
一个SELECT
结果,而不是被放在主变量中。
除这一点之外,FETCH
完全向上兼容于 SQL 标准。
涉及FORWARD
和BACKWARD
的
FETCH
形式,以及形式FETCH
和count
FETCH
ALL
(其中FORWARD
是隐式的)都是
LightDB扩展。
SQL 标准只允许FROM
在游标名之前。使用
IN
的选项或者完全省去它们是一种扩展。
添加GUC参数lightdb_cursor_after_commit, 当参数值为 on, 事务提交后,可以继续操作该游标。 当参数值为 off, 事务提交后,不可以继续操作该游标。 这个参数的默认值为off。