Home Explore Blog CI



postgresql

8th chunk of `doc/src/sgml/plperl.sgml`
eca3e9b3597627edacb248a058c0e9dfcbeb3348601fa6bd0000000100000fa0
 <literal><function>spi_query_prepared(<replaceable>plan</replaceable>, <replaceable>arguments</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_query_prepared</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>
     <term>
      <literal><function>spi_exec_prepared(<replaceable>plan</replaceable> [, <replaceable>attributes</replaceable>], <replaceable>arguments</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_exec_prepared</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>
     <term>
      <literal><function>spi_freeplan(<replaceable>plan</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_freeplan</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>

    <listitem>
    <para>
    <literal>spi_prepare</literal>, <literal>spi_query_prepared</literal>, <literal>spi_exec_prepared</literal>,
    and <literal>spi_freeplan</literal> implement the same functionality but for prepared queries.
    <literal>spi_prepare</literal> accepts a query string with numbered argument placeholders ($1, $2, etc.)
    and a string list of argument types:
<programlisting>
$plan = spi_prepare('SELECT * FROM test WHERE id &gt; $1 AND name = $2',
                                                     'INTEGER', 'TEXT');
</programlisting>
    Once a query plan is prepared by a call to <literal>spi_prepare</literal>, the plan can be used instead
    of the string query, either in <literal>spi_exec_prepared</literal>, where the result is the same as returned
    by <literal>spi_exec_query</literal>, or in <literal>spi_query_prepared</literal> which returns a cursor
    exactly as <literal>spi_query</literal> does, which can be later passed to <literal>spi_fetchrow</literal>.
    The optional second parameter to <literal>spi_exec_prepared</literal> is a hash reference of attributes;
    the only attribute currently supported is <literal>limit</literal>, which
    sets the maximum number of rows returned from the query.
    Omitting <literal>limit</literal> or specifying it as zero results in no
    row limit.
    </para>

    <para>
    The advantage of prepared queries is that is it possible to use one prepared plan for more
    than one query execution. After the plan is not needed anymore, it can be freed with
    <literal>spi_freeplan</literal>:
<programlisting>
CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
        $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now',
                                        'INTERVAL');
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
        return spi_exec_prepared(
                $_SHARED{my_plan},
                $_[0]
        )->{rows}->[0]->{now};
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
        spi_freeplan( $_SHARED{my_plan});
        undef $_SHARED{my_plan};
$$ LANGUAGE plperl;

SELECT init();
SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
SELECT done();

  add_time  |  add_time  |  add_time
------------+------------+------------
 2005-12-10 | 2005-12-11 | 2005-12-12
</programlisting>
    Note that the parameter subscript in <literal>spi_prepare</literal> is defined via
    $1, $2, $3, etc., so avoid declaring query strings in double quotes that might easily
    lead to hard-to-catch bugs.
    </para>

    <para>
    Another example illustrates usage of an optional parameter in <literal>spi_exec_prepared</literal>:
<programlisting>
CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address
                      FROM generate_series(1,3) AS id;

CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$
        $_SHARED{plan} = spi_prepare('SELECT * FROM hosts
                                      WHERE address &lt;&lt; $1', 'inet');
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$

Title: Prepared Queries in PL/Perl
Summary
This section explains the use of prepared queries in PL/Perl for PostgreSQL. It covers four main functions: spi_prepare, spi_query_prepared, spi_exec_prepared, and spi_freeplan. spi_prepare creates a query plan with numbered argument placeholders. The prepared plan can then be used with spi_exec_prepared or spi_query_prepared, which offer similar functionality to spi_exec_query and spi_query respectively. The text provides examples of how to use these functions, including how to set a row limit and how to use shared plans across multiple function calls. It also demonstrates the use of optional parameters in spi_exec_prepared. The main advantage of prepared queries is the ability to reuse a plan for multiple query executions, potentially improving performance. The section concludes with a note on proper syntax for parameter subscripts in spi_prepare to avoid bugs.