row. There are
restrictions on what the cursor's query can be (in particular,
no grouping) and it's best to use <literal>FOR UPDATE</literal> in the
cursor. For more information see the
<xref linkend="sql-declare"/>
reference page.
</para>
<para>
An example:
<programlisting>
UPDATE foo SET dataval = myval WHERE CURRENT OF curs1;
</programlisting>
</para>
</sect3>
<sect3 id="plpgsql-cursor-using-close">
<title><literal>CLOSE</literal></title>
<synopsis>
CLOSE <replaceable>cursor</replaceable>;
</synopsis>
<para>
<command>CLOSE</command> closes the portal underlying an open
cursor. This can be used to release resources earlier than end of
transaction, or to free up the cursor variable to be opened again.
</para>
<para>
An example:
<programlisting>
CLOSE curs1;
</programlisting>
</para>
</sect3>
<sect3 id="plpgsql-cursor-returning">
<title>Returning Cursors</title>
<para>
<application>PL/pgSQL</application> functions can return cursors to the
caller. This is useful to return multiple rows or columns,
especially with very large result sets. To do this, the function
opens the cursor and returns the cursor name to the caller (or simply
opens the cursor using a portal name specified by or otherwise known
to the caller). The caller can then fetch rows from the cursor. The
cursor can be closed by the caller, or it will be closed automatically
when the transaction closes.
</para>
<para>
The portal name used for a cursor can be specified by the
programmer or automatically generated. To specify a portal name,
simply assign a string to the <type>refcursor</type> variable before
opening it. The string value of the <type>refcursor</type> variable
will be used by <command>OPEN</command> as the name of the underlying portal.
However, if the <type>refcursor</type> variable's value is null
(as it will be by default), then
<command>OPEN</command> automatically generates a name that does not
conflict with any existing portal, and assigns it to the
<type>refcursor</type> variable.
</para>
<note>
<para>
Prior to <productname>PostgreSQL</productname> 16, bound cursor
variables were initialized to contain their own names, rather
than being left as null, so that the underlying portal name would
be the same as the cursor variable's name by default. This was
changed because it created too much risk of conflicts between
similarly-named cursors in different functions.
</para>
</note>
<para>
The following example shows one way a cursor name can be supplied by
the caller:
<programlisting>
CREATE TABLE test (col text);
INSERT INTO test VALUES ('123');
CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
BEGIN
OPEN $1 FOR SELECT col FROM test;
RETURN $1;
END;
' LANGUAGE plpgsql;
BEGIN;
SELECT reffunc('funccursor');
FETCH ALL IN funccursor;
COMMIT;
</programlisting>
</para>
<para>
The following example uses automatic cursor name generation:
<programlisting>
CREATE FUNCTION reffunc2() RETURNS refcursor AS '
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT col FROM test;
RETURN ref;
END;
' LANGUAGE plpgsql;
-- need to be in a transaction to use cursors.
BEGIN;
SELECT reffunc2();
reffunc2
--------------------
<unnamed cursor 1>
(1 row)
FETCH ALL IN "<unnamed cursor 1>";
COMMIT;
</programlisting>
</para>
<para>
The following example shows one way to return multiple cursors
from a single function:
<programlisting>
CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
OPEN $1 FOR SELECT