FETCH — 使用游标从一个查询中取回行
FETCH [direction] [ FROM | IN ]cursor_namewheredirectioncan be one of: 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 函数中使用游标,规则会有所不同 — 参见 Section 41.7.3。
directiondirection 定义取数方向和要取的行数。它可以取以下值:
NEXT
取下一行。如果省略了 direction,这就是默认值。
PRIOR取回前一行。
FIRST 取回查询的第一行(等同于 ABSOLUTE 1)。
LAST 取回查询的最后一行(等同于 ABSOLUTE -1)。
ABSOLUTE count 取回查询的第 count 行,或从末尾算起的第 abs( 行(如果 count)count 为负)。如果 count 超出范围,则位置会处于第一行之前或最后一行之后;特别地,ABSOLUTE 0 会定位到第一行之前。
RELATIVE count 取回第 count 个后继行,或第 abs( 个先前行(如果 count)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取回前面所有的行(向后扫描)。
countcount 是一个可以带符号的整数常量,它决定要取回的位置或行数。对于 FORWARD 和 BACKWARD 的情况,指定一个负的 count 等同于改变 FORWARD 和 BACKWARD 的方向。
cursor_name一个已打开游标的名称。
成功完成时,FETCH 命令会返回一个形式如下的命令标签
FETCH count
其中 count 是取回的行数(可能为零)。注意在 psql 中,这个命令标签实际上并不会被显示出来,因为 psql 会改为显示取回的行。
游标应当在声明时带上 SCROLL 选项,如果你打算使用 FETCH 的任何变体,而不只是 FETCH NEXT 或带正数的 FETCH FORWARD。对于简单查询,PostgreSQL 会允许从没有用 SCROLL 声明的游标向后取行,但这种行为最好不要依赖。如果游标是用 NO SCROLL 声明的,则不允许任何向后取行。
ABSOLUTE 取行并不比用相对移动导航到目标行更快:底层实现反正必须遍历所有中间的行。负数的绝对取行甚至更糟:必须把查询读取到末尾才能找到最后一行,然后再从那里反向遍历。不过,倒回到查询的开头(例如 FETCH ABSOLUTE 0)是很快的。
下面的例子使用游标遍历一个表:
BEGIN WORK; -- Set up a cursor: DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films; -- Fetch the first 5 rows in the cursor liahona: 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 the previous row: FETCH PRIOR FROM liahona; code | title | did | date_prod | kind | len -------+---------+-----+------------+--------+------- P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 -- Close the cursor and end the transaction: CLOSE liahona; COMMIT WORK;
SQL 标准定义的 FETCH 仅用于嵌入式 SQL。这里描述的 FETCH 变体会像 SELECT 的结果那样返回数据,而不是把数据放入宿主变量中。除了这一点之外,FETCH 与 SQL 标准完全向上兼容。
FETCH 中涉及 FORWARD 和 BACKWARD 的那些形式,以及 FETCH 和 countFETCH ALL(其中隐含了 FORWARD)这两种形式,都是 PostgreSQL 的扩展。
SQL 标准只允许在游标名之前使用 FROM;可以使用 IN 或者把它们完全省略的选项则是一种扩展。