mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
Some PL/PgSQL documentation improvements from Neil Conway.
This commit is contained in:
parent
c91b8bc537
commit
1b69b122bb
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.6 2002/09/01 16:28:05 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.7 2002/09/14 20:11:16 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="plpgsql">
|
<chapter id="plpgsql">
|
||||||
@ -70,18 +70,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.6 2002/09/01 16:28:05 tgl
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
As each expression and <acronym>SQL</acronym> query is first used
|
As each expression and <acronym>SQL</acronym> query is first used
|
||||||
in the function, the <application>PL/pgSQL</> interpreter creates a
|
in the function, the <application>PL/pgSQL</> interpreter creates
|
||||||
prepared execution plan (using the <acronym>SPI</acronym> manager's
|
a prepared execution plan (using the <acronym>SPI</acronym>
|
||||||
<function>SPI_prepare</function> and
|
manager's <function>SPI_prepare</function> and
|
||||||
<function>SPI_saveplan</function> functions). Subsequent visits
|
<function>SPI_saveplan</function> functions). Subsequent visits
|
||||||
to that expression or query re-use the prepared plan. Thus, a function
|
to that expression or query re-use the prepared plan. Thus, a
|
||||||
with conditional code that contains many statements for which execution
|
function with conditional code that contains many statements for
|
||||||
plans might be required, will only prepare and save those plans
|
which execution plans might be required will only prepare and save
|
||||||
that are really used during the lifetime of the database
|
those plans that are really used during the lifetime of the
|
||||||
connection. This can provide a considerable savings of parsing
|
database connection. This can substantially reduce the total
|
||||||
activity. A disadvantage is that errors in a specific expression
|
amount of time required to parse, and generate query plans for the
|
||||||
or query may not be detected until that part of the function is
|
statements in a procedural language function. A disadvantage is
|
||||||
reached in execution.
|
that errors in a specific expression or query may not be detected
|
||||||
|
until that part of the function is reached in execution.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Once <application>PL/pgSQL</> has made a query plan for a particular
|
Once <application>PL/pgSQL</> has made a query plan for a particular
|
||||||
@ -110,14 +111,26 @@ END;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Because <application>PL/pgSQL</application> saves execution plans in this way, queries that appear
|
Because <application>PL/pgSQL</application> saves execution plans
|
||||||
directly in a <application>PL/pgSQL</application> function must refer to the same tables and fields
|
in this way, queries that appear directly in a
|
||||||
on every execution; that is, you cannot use a parameter as the name of
|
<application>PL/pgSQL</application> function must refer to the
|
||||||
a table or field in a query. To get around
|
same tables and fields on every execution; that is, you cannot use
|
||||||
this restriction, you can construct dynamic queries using the <application>PL/pgSQL</application>
|
a parameter as the name of a table or field in a query. To get
|
||||||
EXECUTE statement --- at the price of constructing a new query plan
|
around this restriction, you can construct dynamic queries using
|
||||||
on every execution.
|
the <application>PL/pgSQL</application> EXECUTE statement --- at
|
||||||
|
the price of constructing a new query plan on every execution.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
The <application>PL/pgSQL</application> EXECUTE statement is not
|
||||||
|
related to the EXECUTE statement supported by the
|
||||||
|
<productname>PostgreSQL</productname> backend. The backend
|
||||||
|
EXECUTE statement cannot be used within PL/PgSQL functions (and
|
||||||
|
is not needed).
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Except for input/output conversion and calculation functions
|
Except for input/output conversion and calculation functions
|
||||||
for user defined types, anything that can be defined in C language
|
for user defined types, anything that can be defined in C language
|
||||||
@ -152,11 +165,11 @@ END;
|
|||||||
<title>Better Performance</title>
|
<title>Better Performance</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<acronym>SQL</acronym> is the language <productname>PostgreSQL</> (and
|
<acronym>SQL</acronym> is the language
|
||||||
most other Relational Databases) use as query
|
<productname>PostgreSQL</> (and most other relational databases)
|
||||||
language. It's portable and easy to learn. But every
|
use as query language. It's portable and easy to learn. But
|
||||||
<acronym>SQL</acronym> statement must be executed
|
every <acronym>SQL</acronym> statement must be executed
|
||||||
individually by the database server.
|
individually by the database server.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -195,9 +208,10 @@ END;
|
|||||||
<title>Portability</title>
|
<title>Portability</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Because <application>PL/pgSQL</application> functions run inside <productname>PostgreSQL</>, these
|
Because <application>PL/pgSQL</application> functions run inside
|
||||||
functions will run on any platform where <productname>PostgreSQL</>
|
<productname>PostgreSQL</>, these functions will run on any
|
||||||
runs. Thus you can reuse code and have less development costs.
|
platform where <productname>PostgreSQL</> runs. Thus you can
|
||||||
|
reuse code and reduce development costs.
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
</sect2>
|
</sect2>
|
||||||
@ -227,16 +241,17 @@ END;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
One good way to develop in <application>PL/pgSQL</> is to simply use the text
|
One good way to develop in <application>PL/pgSQL</> is to simply
|
||||||
editor of your choice to create your functions, and in another
|
use the text editor of your choice to create your functions, and
|
||||||
console, use <command>psql</command> (PostgreSQL's interactive monitor) to load
|
in another window, use <command>psql</command>
|
||||||
those functions. If you are doing it this way, it is a good
|
(<productname>PostgreSQL</>'s interactive monitor) to load those
|
||||||
idea to write the function using <command>CREATE OR REPLACE
|
functions. If you are doing it this way, it is a good idea to
|
||||||
FUNCTION</command>. That way you can reload the file to update
|
write the function using <command>CREATE OR REPLACE
|
||||||
the function definition. For example:
|
FUNCTION</>. That way you can reload the file to update the
|
||||||
|
function definition. For example:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
|
CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
|
||||||
....
|
....
|
||||||
end;
|
end;
|
||||||
' LANGUAGE 'plpgsql';
|
' LANGUAGE 'plpgsql';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@ -645,9 +660,9 @@ RENAME this_var TO that_var;
|
|||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
RENAME appears to be broken as of PostgreSQL 7.2. Fixing this is
|
RENAME appears to be broken as of <productname>PostgreSQL</>
|
||||||
of low priority, since ALIAS covers most of the practical uses of
|
7.3. Fixing this is of low priority, since ALIAS covers most of
|
||||||
RENAME.
|
the practical uses of RENAME.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
@ -898,7 +913,7 @@ END;
|
|||||||
PERFORM <replaceable>query</replaceable>;
|
PERFORM <replaceable>query</replaceable>;
|
||||||
</synopsis>
|
</synopsis>
|
||||||
|
|
||||||
This executes a <literal>SELECT</literal>
|
This executes a <command>SELECT</command>
|
||||||
<replaceable>query</replaceable> and discards the
|
<replaceable>query</replaceable> and discards the
|
||||||
result. <application>PL/pgSQL</application> variables are
|
result. <application>PL/pgSQL</application> variables are
|
||||||
substituted in the query as usual. Also, the special variable
|
substituted in the query as usual. Also, the special variable
|
||||||
@ -1044,6 +1059,10 @@ END;
|
|||||||
<title>Obtaining result status</title>
|
<title>Obtaining result status</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
There are several ways to determine the effect of a command. The
|
||||||
|
first method is to use the <literal>GET DIAGNOSTICS</literal>,
|
||||||
|
which has the form:
|
||||||
|
|
||||||
<synopsis>
|
<synopsis>
|
||||||
GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional> ;
|
GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional> ;
|
||||||
</synopsis>
|
</synopsis>
|
||||||
@ -1166,10 +1185,19 @@ RETURN <replaceable>expression</replaceable>;
|
|||||||
<para>
|
<para>
|
||||||
When a <application>PL/pgSQL</> function is declared to return
|
When a <application>PL/pgSQL</> function is declared to return
|
||||||
<literal>SETOF</literal> <replaceable>sometype</>, the procedure
|
<literal>SETOF</literal> <replaceable>sometype</>, the procedure
|
||||||
to follow is slightly different. The individual items to be returned
|
to follow is slightly different. In that case, the individual
|
||||||
are specified in RETURN NEXT commands, and then a final RETURN with
|
items to return are specified in RETURN NEXT commands, and then a
|
||||||
no argument is given to indicate that the function is done generating
|
final RETURN command with no arguments is used to indicate that
|
||||||
items.
|
the function has finished executing. RETURN NEXT can be used with
|
||||||
|
both scalar and composite data types; in the later case, an
|
||||||
|
entire "table" of results will be returned. Functions that use
|
||||||
|
RETURN NEXT should be called in the following fashion:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
SELECT * FROM some_func();
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
That is, the function is used as a table source in a FROM clause.
|
||||||
|
|
||||||
<synopsis>
|
<synopsis>
|
||||||
RETURN NEXT <replaceable>expression</replaceable>;
|
RETURN NEXT <replaceable>expression</replaceable>;
|
||||||
@ -1184,6 +1212,24 @@ RETURN NEXT <replaceable>expression</replaceable>;
|
|||||||
RETURN, which need have no argument, causes control to exit
|
RETURN, which need have no argument, causes control to exit
|
||||||
the function.
|
the function.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
The current implementation of RETURN NEXT for PL/PgSQL stores
|
||||||
|
the entire result set before returning from the function, as
|
||||||
|
discussed above. That means that if a PL/PgSQL function
|
||||||
|
produces a very large result set, performance may be poor: data
|
||||||
|
will be written to disk to avoid memory exhaustion, but the
|
||||||
|
function itself will not return until the entire
|
||||||
|
result set has been generated. A future version of PL/PgSQL may
|
||||||
|
allow users to allow users to define set-returning functions
|
||||||
|
that do not have this limitation. Currently, the point at which
|
||||||
|
data begins being written to disk is controlled by the
|
||||||
|
<option>SORT_MEM</> configuration variable. Administrators who
|
||||||
|
have sufficient memory to store larger result sets in memory
|
||||||
|
should consider increasing this parameter.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="plpgsql-conditionals">
|
<sect2 id="plpgsql-conditionals">
|
||||||
@ -1904,13 +1950,14 @@ RAISE EXCEPTION ''Inexistent ID --> %'',user_id;
|
|||||||
<title>Trigger Procedures</title>
|
<title>Trigger Procedures</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<application>PL/pgSQL</application> can be used to define trigger
|
<application>PL/pgSQL</application> can be used to define trigger
|
||||||
procedures. A trigger procedure is created with the <command>CREATE
|
procedures. A trigger procedure is created with the
|
||||||
FUNCTION</command> command as a function with no arguments and a return
|
<command>CREATE FUNCTION</> command as a function with no
|
||||||
type of <type>TRIGGER</type>. Note that the function must be declared
|
arguments and a return type of <type>TRIGGER</type>. Note that
|
||||||
with no arguments even if it expects to receive arguments specified
|
the function must be declared with no arguments even if it expects
|
||||||
in <command>CREATE TRIGGER</> --- trigger arguments are passed via
|
to receive arguments specified in <command>CREATE TRIGGER</> ---
|
||||||
<varname>TG_ARGV</>, as described below.
|
trigger arguments are passed via <varname>TG_ARGV</>, as described
|
||||||
|
below.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -2106,14 +2153,15 @@ CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
One painful detail in writing functions in <application>PL/pgSQL</application> is the handling
|
One painful detail in writing functions in
|
||||||
of single quotes. The function's source text in <command>CREATE FUNCTION</command> must
|
<application>PL/pgSQL</application> is the handling of single
|
||||||
be a literal string. Single quotes inside of literal strings must be
|
quotes. The function's source text in <command>CREATE FUNCTION</>
|
||||||
either doubled or quoted with a backslash. We are still looking for
|
must be a literal string. Single quotes inside of literal strings
|
||||||
an elegant alternative. In the meantime, doubling the single quotes
|
must be either doubled or quoted with a backslash. We are still
|
||||||
as in the examples below should be used. Any solution for this
|
looking for an elegant alternative. In the meantime, doubling the
|
||||||
in future versions of <productname>PostgreSQL</productname> will be
|
single quotes as in the examples below should be used. Any
|
||||||
forward compatible.
|
solution for this in future versions of
|
||||||
|
<productname>PostgreSQL</productname> will be forward compatible.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -2504,7 +2552,7 @@ END;
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following procedure grabs rows from a
|
The following procedure grabs rows from a
|
||||||
<literal>SELECT</literal> statement and builds a large function
|
<command>SELECT</command> statement and builds a large function
|
||||||
with the results in <literal>IF</literal> statements, for the
|
with the results in <literal>IF</literal> statements, for the
|
||||||
sake of efficiency. Notice particularly the differences in
|
sake of efficiency. Notice particularly the differences in
|
||||||
cursors, <literal>FOR</literal> loops, and the need to escape
|
cursors, <literal>FOR</literal> loops, and the need to escape
|
||||||
@ -2735,7 +2783,7 @@ show errors
|
|||||||
|
|
||||||
<callout arearefs="co.plpgsql-porting-locktable">
|
<callout arearefs="co.plpgsql-porting-locktable">
|
||||||
<para>
|
<para>
|
||||||
If you do a <literal>LOCK TABLE</literal> in <application>PL/pgSQL</>, the lock
|
If you do a <command>LOCK TABLE</command> in <application>PL/pgSQL</>, the lock
|
||||||
will not be released until the calling transaction is finished.
|
will not be released until the calling transaction is finished.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
@ -2746,7 +2794,7 @@ show errors
|
|||||||
entire function (and other functions called from therein) is
|
entire function (and other functions called from therein) is
|
||||||
executed in a transaction and <productname>PostgreSQL</> rolls back the results if
|
executed in a transaction and <productname>PostgreSQL</> rolls back the results if
|
||||||
something goes wrong. Therefore only one
|
something goes wrong. Therefore only one
|
||||||
<literal>BEGIN</literal> statement is allowed.
|
<command>BEGIN</command> statement is allowed.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
@ -2895,7 +2943,7 @@ END;
|
|||||||
<title>EXECUTE</title>
|
<title>EXECUTE</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <productname>PostgreSQL</> version of <literal>EXECUTE</literal> works
|
The <productname>PostgreSQL</> version of <command>EXECUTE</command> works
|
||||||
nicely, but you have to remember to use
|
nicely, but you have to remember to use
|
||||||
<function>quote_literal(TEXT)</function> and
|
<function>quote_literal(TEXT)</function> and
|
||||||
<function>quote_string(TEXT)</function> as described in <xref
|
<function>quote_string(TEXT)</function> as described in <xref
|
||||||
|
Loading…
Reference in New Issue
Block a user