Home Explore Blog CI



postgresql

7th chunk of `doc/src/sgml/plperl.sgml`
f81dcbed8d93453d5995368f93add1e5931907698496e47b0000000100000fa7
 test_munge();
</programlisting>
    </para>
    </listitem>
    </varlistentry>

    <varlistentry>
     <term>
      <literal><function>spi_query(<replaceable>command</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_query</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>
     <term>
      <literal><function>spi_fetchrow(<replaceable>cursor</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_fetchrow</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>
     <term>
      <literal><function>spi_cursor_close(<replaceable>cursor</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_cursor_close</primary>
       <secondary>in PL/Perl</secondary>
      </indexterm>
     </term>

    <listitem>
    <para>
    <literal>spi_query</literal> and <literal>spi_fetchrow</literal>
    work together as a pair for row sets which might be large, or for cases
    where you wish to return rows as they arrive.
    <literal>spi_fetchrow</literal> works <emphasis>only</emphasis> with
    <literal>spi_query</literal>. The following example illustrates how
    you use them together:

<programlisting>
CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);

CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
    use Digest::MD5 qw(md5_hex);
    my $file = '/usr/share/dict/words';
    my $t = localtime;
    elog(NOTICE, "opening file $file at $t" );
    open my $fh, '&lt;', $file # ooh, it's a file access!
        or elog(ERROR, "cannot open $file for reading: $!");
    my @words = &lt;$fh&gt;;
    close $fh;
    $t = localtime;
    elog(NOTICE, "closed file $file at $t");
    chomp(@words);
    my $row;
    my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
    while (defined ($row = spi_fetchrow($sth))) {
        return_next({
            the_num =&gt; $row-&gt;{a},
            the_text =&gt; md5_hex($words[rand @words])
        });
    }
    return;
$$ LANGUAGE plperlu;

SELECT * from lotsa_md5(500);
</programlisting>
    </para>

    <para>
     Normally, <function>spi_fetchrow</function> should be repeated until it
     returns <literal>undef</literal>, indicating that there are no more
     rows to read.  The cursor returned by <literal>spi_query</literal>
     is automatically freed when
     <function>spi_fetchrow</function> returns <literal>undef</literal>.
     If you do not wish to read all the rows, instead call
     <function>spi_cursor_close</function> to free the cursor.
     Failure to do so will result in memory leaks.
    </para>

    </listitem>
    </varlistentry>

    <varlistentry>
     <term>
      <literal><function>spi_prepare(<replaceable>command</replaceable>, <replaceable>argument types</replaceable>)</function></literal>
      <indexterm>
       <primary>spi_prepare</primary>
       <secondary>in PL/Perl</secondary>
     </indexterm>
     </term>
     <term>
      <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

Title: Advanced Database Access Functions in PL/Perl
Summary
This section describes advanced database access functions in PL/Perl for PostgreSQL. It focuses on spi_query, spi_fetchrow, and spi_cursor_close, which are used for handling large result sets or returning rows as they arrive. The text provides a detailed example of using spi_query and spi_fetchrow in a PL/Perl function that generates MD5 hashes. It explains how to properly use and free cursors to avoid memory leaks. The section also introduces prepared statement functions like spi_prepare, spi_query_prepared, spi_exec_prepared, and spi_freeplan, though their detailed explanations are not included in the given excerpt. These functions offer more efficient ways to execute repeated SQL queries with different parameters.