4 41.7.1. Declaring Cursor Variables
5 41.7.2. Opening Cursors
7 41.7.4. Looping through a Cursor's Result
9 Rather than executing a whole query at once, it is possible to set up a
10 cursor that encapsulates the query, and then read the query result a
11 few rows at a time. One reason for doing this is to avoid memory
12 overrun when the result contains a large number of rows. (However,
13 PL/pgSQL users do not normally need to worry about that, since FOR
14 loops automatically use a cursor internally to avoid memory problems.)
15 A more interesting usage is to return a reference to a cursor that a
16 function has created, allowing the caller to read the rows. This
17 provides an efficient way to return large row sets from functions.
19 41.7.1. Declaring Cursor Variables #
21 All access to cursors in PL/pgSQL goes through cursor variables, which
22 are always of the special data type refcursor. One way to create a
23 cursor variable is just to declare it as a variable of type refcursor.
24 Another way is to use the cursor declaration syntax, which in general
26 name [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR query;
28 (FOR can be replaced by IS for Oracle compatibility.) If SCROLL is
29 specified, the cursor will be capable of scrolling backward; if NO
30 SCROLL is specified, backward fetches will be rejected; if neither
31 specification appears, it is query-dependent whether backward fetches
32 will be allowed. arguments, if specified, is a comma-separated list of
33 pairs name datatype that define names to be replaced by parameter
34 values in the given query. The actual values to substitute for these
35 names will be specified later, when the cursor is opened.
40 curs2 CURSOR FOR SELECT * FROM tenk1;
41 curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;
43 All three of these variables have the data type refcursor, but the
44 first can be used with any query, while the second has a fully
45 specified query already bound to it, and the last has a parameterized
46 query bound to it. (key will be replaced by an integer parameter value
47 when the cursor is opened.) The variable curs1 is said to be unbound
48 since it is not bound to any particular query.
50 The SCROLL option cannot be used when the cursor's query uses FOR
51 UPDATE/SHARE. Also, it is best to use NO SCROLL with a query that
52 involves volatile functions. The implementation of SCROLL assumes that
53 re-reading the query's output will give consistent results, which a
54 volatile function might not do.
56 41.7.2. Opening Cursors #
58 Before a cursor can be used to retrieve rows, it must be opened. (This
59 is the equivalent action to the SQL command DECLARE CURSOR.) PL/pgSQL
60 has three forms of the OPEN statement, two of which use unbound cursor
61 variables while the third uses a bound cursor variable.
65 Bound cursor variables can also be used without explicitly opening the
66 cursor, via the FOR statement described in Section 41.7.4. A FOR loop
67 will open the cursor and then close it again when the loop completes.
69 Opening a cursor involves creating a server-internal data structure
70 called a portal, which holds the execution state for the cursor's
71 query. A portal has a name, which must be unique within the session for
72 the duration of the portal's existence. By default, PL/pgSQL will
73 assign a unique name to each portal it creates. However, if you assign
74 a non-null string value to a cursor variable, that string will be used
75 as its portal name. This feature can be used as described in
78 41.7.2.1. OPEN FOR query #
80 OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR query;
82 The cursor variable is opened and given the specified query to execute.
83 The cursor cannot be open already, and it must have been declared as an
84 unbound cursor variable (that is, as a simple refcursor variable). The
85 query must be a SELECT, or something else that returns rows (such as
86 EXPLAIN). The query is treated in the same way as other SQL commands in
87 PL/pgSQL: PL/pgSQL variable names are substituted, and the query plan
88 is cached for possible reuse. When a PL/pgSQL variable is substituted
89 into the cursor query, the value that is substituted is the one it has
90 at the time of the OPEN; subsequent changes to the variable will not
91 affect the cursor's behavior. The SCROLL and NO SCROLL options have the
92 same meanings as for a bound cursor.
95 OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;
97 41.7.2.2. OPEN FOR EXECUTE #
99 OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR EXECUTE query_string
100 [ USING expression [, ... ] ];
102 The cursor variable is opened and given the specified query to execute.
103 The cursor cannot be open already, and it must have been declared as an
104 unbound cursor variable (that is, as a simple refcursor variable). The
105 query is specified as a string expression, in the same way as in the
106 EXECUTE command. As usual, this gives flexibility so the query plan can
107 vary from one run to the next (see Section 41.11.2), and it also means
108 that variable substitution is not done on the command string. As with
109 EXECUTE, parameter values can be inserted into the dynamic command via
110 format() and USING. The SCROLL and NO SCROLL options have the same
111 meanings as for a bound cursor.
114 OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING
117 In this example, the table name is inserted into the query via
118 format(). The comparison value for col1 is inserted via a USING
119 parameter, so it needs no quoting.
121 41.7.2.3. Opening a Bound Cursor #
123 OPEN bound_cursorvar [ ( [ argument_name { := | => } ] argument_value [, ...] )
126 This form of OPEN is used to open a cursor variable whose query was
127 bound to it when it was declared. The cursor cannot be open already. A
128 list of actual argument value expressions must appear if and only if
129 the cursor was declared to take arguments. These values will be
130 substituted in the query.
132 The query plan for a bound cursor is always considered cacheable; there
133 is no equivalent of EXECUTE in this case. Notice that SCROLL and NO
134 SCROLL cannot be specified in OPEN, as the cursor's scrolling behavior
135 was already determined.
137 Argument values can be passed using either positional or named
138 notation. In positional notation, all arguments are specified in order.
139 In named notation, each argument's name is specified using := or => to
140 separate it from the argument expression. Similar to calling functions,
141 described in Section 4.3, it is also allowed to mix positional and
144 Examples (these use the cursor declaration examples above):
147 OPEN curs3(key := 42);
148 OPEN curs3(key => 42);
150 Because variable substitution is done on a bound cursor's query, there
151 are really two ways to pass values into the cursor: either with an
152 explicit argument to OPEN, or implicitly by referencing a PL/pgSQL
153 variable in the query. However, only variables declared before the
154 bound cursor was declared will be substituted into it. In either case
155 the value to be passed is determined at the time of the OPEN. For
156 example, another way to get the same effect as the curs3 example above
160 curs4 CURSOR FOR SELECT * FROM tenk1 WHERE unique1 = key;
165 41.7.3. Using Cursors #
167 Once a cursor has been opened, it can be manipulated with the
168 statements described here.
170 These manipulations need not occur in the same function that opened the
171 cursor to begin with. You can return a refcursor value out of a
172 function and let the caller operate on the cursor. (Internally, a
173 refcursor value is simply the string name of the portal containing the
174 active query for the cursor. This name can be passed around, assigned
175 to other refcursor variables, and so on, without disturbing the
178 All portals are implicitly closed at transaction end. Therefore a
179 refcursor value is usable to reference an open cursor only until the
180 end of the transaction.
184 FETCH [ direction { FROM | IN } ] cursor INTO target;
186 FETCH retrieves the next row (in the indicated direction) from the
187 cursor into a target, which might be a row variable, a record variable,
188 or a comma-separated list of simple variables, just like SELECT INTO.
189 If there is no suitable row, the target is set to NULL(s). As with
190 SELECT INTO, the special variable FOUND can be checked to see whether a
191 row was obtained or not. If no row is obtained, the cursor is
192 positioned after the last row or before the first row, depending on the
195 The direction clause can be any of the variants allowed in the SQL
196 FETCH command except the ones that can fetch more than one row; namely,
197 it can be NEXT, PRIOR, FIRST, LAST, ABSOLUTE count, RELATIVE count,
198 FORWARD, or BACKWARD. Omitting direction is the same as specifying
199 NEXT. In the forms using a count, the count can be any integer-valued
200 expression (unlike the SQL FETCH command, which only allows an integer
201 constant). direction values that require moving backward are likely to
202 fail unless the cursor was declared or opened with the SCROLL option.
204 cursor must be the name of a refcursor variable that references an open
208 FETCH curs1 INTO rowvar;
209 FETCH curs2 INTO foo, bar, baz;
210 FETCH LAST FROM curs3 INTO x, y;
211 FETCH RELATIVE -2 FROM curs4 INTO x;
215 MOVE [ direction { FROM | IN } ] cursor;
217 MOVE repositions a cursor without retrieving any data. MOVE works like
218 the FETCH command, except it only repositions the cursor and does not
219 return the row moved to. The direction clause can be any of the
220 variants allowed in the SQL FETCH command, including those that can
221 fetch more than one row; the cursor is positioned to the last such row.
222 (However, the case in which the direction clause is simply a count
223 expression with no key word is deprecated in PL/pgSQL. That syntax is
224 ambiguous with the case where the direction clause is omitted
225 altogether, and hence it may fail if the count is not a constant.) As
226 with SELECT INTO, the special variable FOUND can be checked to see
227 whether there was a row to move to. If there is no such row, the cursor
228 is positioned after the last row or before the first row, depending on
229 the movement direction.
233 MOVE LAST FROM curs3;
234 MOVE RELATIVE -2 FROM curs4;
235 MOVE FORWARD 2 FROM curs4;
237 41.7.3.3. UPDATE/DELETE WHERE CURRENT OF #
239 UPDATE table SET ... WHERE CURRENT OF cursor;
240 DELETE FROM table WHERE CURRENT OF cursor;
242 When a cursor is positioned on a table row, that row can be updated or
243 deleted using the cursor to identify the row. There are restrictions on
244 what the cursor's query can be (in particular, no grouping) and it's
245 best to use FOR UPDATE in the cursor. For more information see the
246 DECLARE reference page.
249 UPDATE foo SET dataval = myval WHERE CURRENT OF curs1;
255 CLOSE closes the portal underlying an open cursor. This can be used to
256 release resources earlier than end of transaction, or to free up the
257 cursor variable to be opened again.
262 41.7.3.5. Returning Cursors #
264 PL/pgSQL functions can return cursors to the caller. This is useful to
265 return multiple rows or columns, especially with very large result
266 sets. To do this, the function opens the cursor and returns the cursor
267 name to the caller (or simply opens the cursor using a portal name
268 specified by or otherwise known to the caller). The caller can then
269 fetch rows from the cursor. The cursor can be closed by the caller, or
270 it will be closed automatically when the transaction closes.
272 The portal name used for a cursor can be specified by the programmer or
273 automatically generated. To specify a portal name, simply assign a
274 string to the refcursor variable before opening it. The string value of
275 the refcursor variable will be used by OPEN as the name of the
276 underlying portal. However, if the refcursor variable's value is null
277 (as it will be by default), then OPEN automatically generates a name
278 that does not conflict with any existing portal, and assigns it to the
283 Prior to PostgreSQL 16, bound cursor variables were initialized to
284 contain their own names, rather than being left as null, so that the
285 underlying portal name would be the same as the cursor variable's name
286 by default. This was changed because it created too much risk of
287 conflicts between similarly-named cursors in different functions.
289 The following example shows one way a cursor name can be supplied by
291 CREATE TABLE test (col text);
292 INSERT INTO test VALUES ('123');
294 CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
296 OPEN $1 FOR SELECT col FROM test;
302 SELECT reffunc('funccursor');
303 FETCH ALL IN funccursor;
306 The following example uses automatic cursor name generation:
307 CREATE FUNCTION reffunc2() RETURNS refcursor AS '
311 OPEN ref FOR SELECT col FROM test;
316 -- need to be in a transaction to use cursors.
325 FETCH ALL IN "<unnamed cursor 1>";
328 The following example shows one way to return multiple cursors from a
330 CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
332 OPEN $1 FOR SELECT * FROM table_1;
334 OPEN $2 FOR SELECT * FROM table_2;
339 -- need to be in a transaction to use cursors.
342 SELECT * FROM myfunc('a', 'b');
348 41.7.4. Looping through a Cursor's Result #
350 There is a variant of the FOR statement that allows iterating through
351 the rows returned by a cursor. The syntax is:
353 FOR recordvar IN bound_cursorvar [ ( [ argument_name { := | => } ] argument_valu
358 The cursor variable must have been bound to some query when it was
359 declared, and it cannot be open already. The FOR statement
360 automatically opens the cursor, and it closes the cursor again when the
361 loop exits. A list of actual argument value expressions must appear if
362 and only if the cursor was declared to take arguments. These values
363 will be substituted in the query, in just the same way as during an
364 OPEN (see Section 41.7.2.3).
366 The variable recordvar is automatically defined as type record and
367 exists only inside the loop (any existing definition of the variable
368 name is ignored within the loop). Each row returned by the cursor is
369 successively assigned to this record variable and the loop body is