Home Explore Blog CI



postgresql

40th chunk of `doc/src/sgml/plpgsql.sgml`
8fb7389ae7e41dc09673e0b52b479f80fc2154cf5bc08a850000000100000fa1
 <command>GET DIAGNOSTICS</command>
    command.  The second and any subsequent lines refer to calling functions
    further up the call stack.  For example:

<programlisting>
CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$
BEGIN
  RETURN inner_func();
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$
DECLARE
  stack text;
BEGIN
  GET DIAGNOSTICS stack = PG_CONTEXT;
  RAISE NOTICE E'--- Call Stack ---\n%', stack;
  RETURN 1;
END;
$$ LANGUAGE plpgsql;

SELECT outer_func();

NOTICE:  --- Call Stack ---
PL/pgSQL function inner_func() line 5 at GET DIAGNOSTICS
PL/pgSQL function outer_func() line 3 at RETURN
CONTEXT:  PL/pgSQL function outer_func() line 3 at RETURN
 outer_func
 ------------
           1
(1 row)
</programlisting>

   </para>

   <para>
    <literal>GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT</literal>
    returns the same sort of stack trace, but describing the location
    at which an error was detected, rather than the current location.
   </para>
  </sect2>
  </sect1>

  <sect1 id="plpgsql-cursors">
   <title>Cursors</title>

   <indexterm zone="plpgsql-cursors">
    <primary>cursor</primary>
    <secondary>in PL/pgSQL</secondary>
   </indexterm>

   <para>
    Rather than executing a whole query at once, it is possible to set
    up a <firstterm>cursor</firstterm> that encapsulates the query, and then read
    the query result a few rows at a time. One reason for doing this is
    to avoid memory overrun when the result contains a large number of
    rows. (However, <application>PL/pgSQL</application> users do not normally need
    to worry about that, since <literal>FOR</literal> loops automatically use a cursor
    internally to avoid memory problems.) A more interesting usage is to
    return a reference to a cursor that a function has created, allowing the
    caller to read the rows. This provides an efficient way to return
    large row sets from functions.
   </para>

   <sect2 id="plpgsql-cursor-declarations">
    <title>Declaring Cursor Variables</title>

    <para>
     All access to cursors in <application>PL/pgSQL</application> goes through
     cursor variables, which are always of the special data type
     <type>refcursor</type>.  One way to create a cursor variable
     is just to declare it as a variable of type <type>refcursor</type>.
     Another way is to use the cursor declaration syntax,
     which in general is:
<synopsis>
<replaceable>name</replaceable> <optional> <optional> NO </optional> SCROLL </optional> CURSOR <optional> ( <replaceable>arguments</replaceable> ) </optional> FOR <replaceable>query</replaceable>;
</synopsis>
     (<literal>FOR</literal> can be replaced by <literal>IS</literal> for
     <productname>Oracle</productname> compatibility.)
     If <literal>SCROLL</literal> is specified, the cursor will be capable of
     scrolling backward; if <literal>NO SCROLL</literal> is specified, backward
     fetches will be rejected; if neither specification appears, it is
     query-dependent whether backward fetches will be allowed.
     <replaceable>arguments</replaceable>, if specified, is a
     comma-separated list of pairs <literal><replaceable>name</replaceable>
     <replaceable>datatype</replaceable></literal> that define names to be
     replaced by parameter values in the given query.  The actual
     values to substitute for these names will be specified later,
     when the cursor is opened.
    </para>
    <para>
     Some examples:
<programlisting>
DECLARE
    curs1 refcursor;
    curs2 CURSOR FOR SELECT * FROM tenk1;
    curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;
</programlisting>
     All three of these variables have the data type <type>refcursor</type>,
     but the first can be used with any query, while the second has
     a fully specified query already <firstterm>bound</firstterm> to it, and the last
     has a parameterized query bound to it.  (<literal>key</literal> will be

Title: Call Stacks, Cursors, and Cursor Variable Declarations in PL/pgSQL
Summary
This section continues the discussion of call stacks in PL/pgSQL, explaining that `GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT` provides a stack trace showing the error's location. It then introduces cursors as a way to fetch query results in batches, which is especially useful for large datasets. It describes the `refcursor` data type and the syntax for declaring cursor variables, including options for scrollability and parameterized queries.