FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
WHERE c.relkind = 'm'
ORDER BY 1
LOOP
-- Now "mviews" has one record with information about the materialized view
RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...',
quote_ident(mviews.mv_schema),
quote_ident(mviews.mv_name),
quote_ident(mviews.owner);
EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name);
END LOOP;
RAISE NOTICE 'Done refreshing materialized views.';
RETURN 1;
END;
$$ LANGUAGE plpgsql;
</programlisting>
If the loop is terminated by an <literal>EXIT</literal> statement, the last
assigned row value is still accessible after the loop.
</para>
<para>
The <replaceable>query</replaceable> used in this type of <literal>FOR</literal>
statement can be any SQL command that returns rows to the caller:
<command>SELECT</command> is the most common case,
but you can also use <command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>, or <command>MERGE</command> with a
<literal>RETURNING</literal> clause. Some utility
commands such as <command>EXPLAIN</command> will work too.
</para>
<para>
<application>PL/pgSQL</application> variables are replaced by query parameters,
and the query plan is cached for possible re-use, as discussed in
detail in <xref linkend="plpgsql-var-subst"/> and
<xref linkend="plpgsql-plan-caching"/>.
</para>
<para>
The <literal>FOR-IN-EXECUTE</literal> statement is another way to iterate over
rows:
<synopsis>
<optional> <<<replaceable>label</replaceable>>> </optional>
FOR <replaceable>target</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional> LOOP
<replaceable>statements</replaceable>
END LOOP <optional> <replaceable>label</replaceable> </optional>;
</synopsis>
This is like the previous form, except that the source query
is specified as a string expression, which is evaluated and replanned
on each entry to the <literal>FOR</literal> loop. This allows the programmer to
choose the speed of a preplanned query or the flexibility of a dynamic
query, just as with a plain <command>EXECUTE</command> statement.
As with <command>EXECUTE</command>, parameter values can be inserted
into the dynamic command via <literal>USING</literal>.
</para>
<para>
Another way to specify the query whose results should be iterated
through is to declare it as a cursor. This is described in
<xref linkend="plpgsql-cursor-for-loop"/>.
</para>
</sect2>
<sect2 id="plpgsql-foreach-array">
<title>Looping through Arrays</title>
<para>
The <literal>FOREACH</literal> loop is much like a <literal>FOR</literal> loop,
but instead of iterating through the rows returned by an SQL query,
it iterates through the elements of an array value.
(In general, <literal>FOREACH</literal> is meant for looping through
components of a composite-valued expression; variants for looping
through composites besides arrays may be added in future.)
The <literal>FOREACH</literal> statement to loop over an array is:
<synopsis>
<optional> <<<replaceable>label</replaceable>>> </optional>
FOREACH <replaceable>target</replaceable> <optional> SLICE <replaceable>number</replaceable> </optional> IN ARRAY <replaceable>expression</replaceable> LOOP
<replaceable>statements</replaceable>
END LOOP <optional> <replaceable>label</replaceable> </optional>;
</synopsis>
</para>
<para>
Without <literal>SLICE</literal>, or if <literal>SLICE 0</literal> is specified,
the loop iterates through individual elements of the array produced
by