EXECUTE <replaceable class="command">command-string</replaceable> <optional> INTO <optional>STRICT</optional> <replaceable>target</replaceable> </optional> <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional>;
</synopsis>
where <replaceable>command-string</replaceable> is an expression
yielding a string (of type <type>text</type>) containing the
command to be executed. The optional <replaceable>target</replaceable>
is a record variable, a row variable, or a comma-separated list of
simple variables and record/row fields, into which the results of
the command will be stored. The optional <literal>USING</literal> expressions
supply values to be inserted into the command.
</para>
<para>
No substitution of <application>PL/pgSQL</application> variables is done on the
computed command string. Any required variable values must be inserted
in the command string as it is constructed; or you can use parameters
as described below.
</para>
<para>
Also, there is no plan caching for commands executed via
<command>EXECUTE</command>. Instead, the command is always planned
each time the statement is run. Thus the command
string can be dynamically created within the function to perform
actions on different tables and columns.
</para>
<para>
The <literal>INTO</literal> clause specifies where the results of
an SQL command returning rows should be assigned. If a row variable
or variable list is provided, it must exactly match the structure
of the command's results; if a
record variable is provided, it will configure itself to match the
result structure automatically. If multiple rows are returned,
only the first will be assigned to the <literal>INTO</literal>
variable(s). If no rows are returned, NULL is assigned to the
<literal>INTO</literal> variable(s). If no <literal>INTO</literal>
clause is specified, the command results are discarded.
</para>
<para>
If the <literal>STRICT</literal> option is given, an error is reported
unless the command produces exactly one row.
</para>
<para>
The command string can use parameter values, which are referenced
in the command as <literal>$1</literal>, <literal>$2</literal>, etc.
These symbols refer to values supplied in the <literal>USING</literal>
clause. This method is often preferable to inserting data values
into the command string as text: it avoids run-time overhead of
converting the values to text and back, and it is much less prone
to SQL-injection attacks since there is no need for quoting or escaping.
An example is:
<programlisting>
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
</programlisting>
</para>
<para>
Note that parameter symbols can only be used for data values
— if you want to use dynamically determined table or column
names, you must insert them into the command string textually.
For example, if the preceding query needed to be done against a
dynamically selected table, you could do this:
<programlisting>
EXECUTE 'SELECT count(*) FROM '
|| quote_ident(tabname)
|| ' WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
</programlisting>
A cleaner approach is to use <function>format()</function>'s <literal>%I</literal>
specification to insert table or column names with automatic quoting:
<programlisting>
EXECUTE format('SELECT count(*) FROM %I '
'WHERE inserted_by = $1 AND inserted <= $2', tabname)
INTO c
USING checked_user, checked_date;
</programlisting>
(This example relies on the SQL rule that string literals separated by a
newline are implicitly concatenated.)
</para>
<para>
Another restriction on parameter