Home Explore Blog CI



postgresql

19th chunk of `doc/src/sgml/plpgsql.sgml`
e91d5a5ec4e9646cd109e60468bd0c39595a5746652d3c030000000100000fa1
 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 &lt;= $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 &lt;= $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 symbols is that they only work in
     optimizable SQL commands
     (<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
     <command>DELETE</command>, <command>MERGE</command>, and certain commands containing one of these).
     In other statement
     types (generically called utility statements), you must insert
     values textually even if they are just data values.
    </para>

    <para>
     An <command>EXECUTE</command> with a simple constant command string and some
     <literal>USING</literal> parameters, as in the first example above, is
     functionally equivalent to just writing the command directly in
     <application>PL/pgSQL</application> and allowing replacement of
     <application>PL/pgSQL</application> variables to happen automatically.
     The important difference is that <command>EXECUTE</command> will re-plan
     the command on each execution, generating a plan that is specific
     to the current parameter values; whereas
     <application>PL/pgSQL</application> may otherwise create a generic plan
     and cache it for re-use.  In situations where the best plan depends
     strongly on the parameter values, it can be helpful to use
     <command>EXECUTE</command> to positively ensure that a generic plan is not
     selected.
    </para>

    <para>
     <command>SELECT INTO</command> is not currently supported within
     <command>EXECUTE</command>; instead, execute a plain <command>SELECT</command>
     command and specify <literal>INTO</literal> as part of the <command>EXECUTE</command>
     itself.
    </para>

   <note>
    <para>
     The <application>PL/pgSQL</application>
     <command>EXECUTE</command> statement is not related to the
     <link linkend="sql-execute"><command>EXECUTE</command></link> SQL
     statement supported by the
     <productname>PostgreSQL</productname> server. The server's
     <command>EXECUTE</command> statement cannot be used directly within
     <application>PL/pgSQL</application> functions (and is not needed).
    </para>
   </note>

   <example id="plpgsql-quote-literal-example">
   <title>Quoting Values in Dynamic Queries</title>

    <indexterm>
     <primary>quote_ident</primary>
     <secondary>use in PL/pgSQL</secondary>
    </indexterm>

    <indexterm>
     <primary>quote_literal</primary>
     <secondary>use in PL/pgSQL</secondary>
    </indexterm>

    <indexterm>
     <primary>quote_nullable</primary>
     <secondary>use in PL/pgSQL</secondary>
    </indexterm>

    <indexterm>
     <primary>format</primary>
     <secondary>use in PL/pgSQL</secondary>
    </indexterm>

    <para>
     When working with dynamic commands you will often have to handle escaping
     of single quotes.  The recommended method for quoting fixed text in your
     function body is dollar quoting.  (If you have legacy code that does
     not use dollar quoting, please refer to the
     overview in <xref linkend="plpgsql-quote-tips"/>, which can save you
     some

Title: EXECUTE Statement Restrictions and Best Practices: Dynamic Queries and Parameter Usage
Summary
Parameter symbols in EXECUTE work only for optimizable SQL commands (SELECT, INSERT, UPDATE, DELETE, MERGE). Other statements require textual value insertion. Using EXECUTE with parameters ensures a plan specific to those values, potentially avoiding a less optimal generic plan. SELECT INTO is not supported within EXECUTE; use a plain SELECT with INTO in the EXECUTE itself. PL/pgSQL's EXECUTE differs from the server's EXECUTE statement. When building dynamic queries, use dollar quoting for fixed text and format() to prevent SQL injection. quote_ident, quote_literal, and quote_nullable are used for quoting.