function's return type as described for assignments.
<optional><<label>></optional>
LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
An unconditional loop that must be terminated explicitly
by an EXIT statement. The optional label can be used by
EXIT statements of nested loops to specify which level of
nesting should be terminated.
<synopsis>
<optional><<label>></optional>
WHILE <replaceable>expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
A conditional loop that is executed as long as the evaluation
of <replaceable>expression</replaceable> is true.
<synopsis>
<optional><<label>></optional>
FOR <replaceable>name</replaceable> IN <optional> REVERSE </optional> <replaceable>expression</replaceable> .. <replaceable>expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
A loop that iterates over a range of integer values. The variable
<replaceable>name</replaceable> is automatically created as type
integer and exists only inside the loop. The two expressions giving
the lower and upper bound of the range are evaluated only when entering
the loop. The iteration step is always 1.
<synopsis>
<optional><<label>></optional>
FOR <replaceable>record | row</replaceable> IN <replaceable>select_clause</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
The record or row is assigned all the rows resulting from the select
clause and the loop body is executed for each row. If the loop is
terminated with an EXIT statement, the last assigned row is still
accessible after the loop.
<synopsis>
<optional><<label>></optional>
FOR <replaceable>record | row</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
This is like the previous form, except that the source SELECT
statement is specified as a string expression, which is evaluated
and re-planned on each entry to the FOR loop. This allows the
programmer to choose the speed of a pre-planned query or the
flexibility of a dynamic query, just as with a plain EXECUTE
statement.
<synopsis>
EXIT <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>expression</replaceable> </optional>;
</synopsis>
If no <replaceable>label</replaceable> given,
the innermost loop is terminated and the
statement following END LOOP is executed next.
If <replaceable>label</replaceable> is given, it
must be the label of the current or an upper level of nested loop
blocks. Then the named loop or block is terminated and control
continues with the statement after the loops/blocks corresponding
Data type oid; the object ID of the table that caused the
Examples:
trigger invocation.
<programlisting>
LOOP
--somecomputations
IFcount>0THEN
EXIT;--exitloop
ENDIF;
ENDLOOP;
LOOP
--somecomputations
EXITWHENcount>0;
ENDLOOP;
BEGIN
--somecomputations
IFstocks>100000THEN
EXIT;--illegal.Can't use EXIT outside of a LOOP
END IF;
END;
</programlisting>
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term><varname>TG_RELNAME</varname></term>
<term>
WHILE
</term>
<listitem>
<listitem>
<para>
<para>
Data type name; the name of the table that caused the trigger
With the WHILE statement, you can loop through a
invocation.
sequence of statements as long as the evaluation of
the condition expression is true.
</para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TG_NARGS</varname></term>
<listitem>
<para>
<para>
Data type integer; the number of arguments given to the trigger
<synopsis>
procedure in the CREATE TRIGGER statement.
<optional><<label>></optional>
WHILE <replaceable>expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
<para>
For example:
</para>
<programlisting>
WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP
-- some computations here
END LOOP;
WHILE NOT boolean_expression LOOP
-- some computations here
END LOOP;
</programlisting>
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term><varname>TG_ARGV[]</varname></term>
<term>
FOR
</term>
<listitem>
<listitem>
<para>
<para>
Data type array of <type>text</type>; the arguments from the CREATE TRIGGER statement.
<synopsis>
The index counts from 0 and can be given as an expression. Invalid
<optional><<label>></optional>
indices (< 0 or >= tg_nargs) result in a NULL value.
FOR <replaceable>name</replaceable> IN <optional> REVERSE </optional> <replaceable>expression</replaceable> .. <replaceable>expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP;
</synopsis>
A loop that iterates over a range of integer values. The variable
<replaceable>name</replaceable> is automatically created as type
integer and exists only inside the loop. The two expressions giving
the lower and upper bound of the range are evaluated only when entering
the loop. The iteration step is always 1.
</para>
<para>
Some examples of FOR loops (see <xref linkend="plpgsql-description-records"></xref> for
iterating over records in FOR loops):
<programlisting>
FOR i IN 1..10 LOOP
-- some expressions here
RAISE NOTICE 'iis%',i;
END LOOP;
FOR i IN REVERSE 1..10 LOOP
-- some expressions here
END LOOP;
</programlisting>
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
</variablelist>
</variablelist>
</sect3>
</sect2>
<!-- **** PL/pgSQL records **** -->
<sect2 id="plpgsql-description-records">
<title>Working with RECORDs</title>
<para>
Records are similar to rowtypes, but they have no predefined structure.
They are used in selections and FOR loops to hold one actual