via the following functions:
</para>
<variablelist>
<varlistentry>
<term>
<literal><function>spi_exec_query</function>(<replaceable>query</replaceable> [, <replaceable>limit</replaceable>])</literal>
<indexterm>
<primary>spi_exec_query</primary>
<secondary>in PL/Perl</secondary>
</indexterm>
</term>
<listitem>
<para>
<function>spi_exec_query</function> executes an SQL command and
returns the entire row set as a reference to an array of hash references.
If <replaceable>limit</replaceable> is specified and is greater than zero,
then <function>spi_exec_query</function> retrieves at
most <replaceable>limit</replaceable> rows, much as if the query included
a <literal>LIMIT</literal> clause. Omitting <replaceable>limit</replaceable>
or specifying it as zero results in no row limit.
</para>
<para>
<emphasis>You should only use this command when you know
that the result set will be relatively small.</emphasis> Here is an
example of a query (<command>SELECT</command> command) with the
optional maximum number of rows:
<programlisting>
$rv = spi_exec_query('SELECT * FROM my_table', 5);
</programlisting>
This returns up to 5 rows from the table
<literal>my_table</literal>. If <literal>my_table</literal>
has a column <literal>my_column</literal>, you can get that
value from row <literal>$i</literal> of the result like this:
<programlisting>
$foo = $rv->{rows}[$i]->{my_column};
</programlisting>
The total number of rows returned from a <command>SELECT</command>
query can be accessed like this:
<programlisting>
$nrows = $rv->{processed}
</programlisting>
</para>
<para>
Here is an example using a different command type:
<programlisting>
$query = "INSERT INTO my_table VALUES (1, 'test')";
$rv = spi_exec_query($query);
</programlisting>
You can then access the command status (e.g.,
<literal>SPI_OK_INSERT</literal>) like this:
<programlisting>
$res = $rv->{status};
</programlisting>
To get the number of rows affected, do:
<programlisting>
$nrows = $rv->{processed};
</programlisting>
</para>
<para>
Here is a complete example:
<programlisting>
CREATE TABLE test (
i int,
v varchar
);
INSERT INTO test (i, v) VALUES (1, 'first line');
INSERT INTO test (i, v) VALUES (2, 'second line');
INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal');
CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
my $rv = spi_exec_query('select i, v from test;');
my $status = $rv->{status};
my $nrows = $rv->{processed};
foreach my $rn (0 .. $nrows - 1) {
my $row = $rv->{rows}[$rn];
$row->{i} += 200 if defined($row->{i});
$row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
return_next($row);
}
return undef;
$$ LANGUAGE plperl;
SELECT * FROM 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