Fix markup. (A <keyword> isn't what it is in SQL.) Add jungle of more
markup. ;-)
This commit is contained in:
parent
fa877ed8ee
commit
496373e2e4
@ -1,9 +1,9 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.20 2001/02/19 19:49:52 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.21 2001/02/21 17:50:38 petere Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="plsql">
|
<chapter id="plsql">
|
||||||
<title>PL/pgSQL - SQL Procedural Language</title>
|
<title>PL/pgSQL - <acronym>SQL</acronym> Procedural Language</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
PL/pgSQL is a loadable procedural language for the
|
PL/pgSQL is a loadable procedural language for the
|
||||||
@ -64,8 +64,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.20 2001/02/19 19:49:52
|
|||||||
<para>
|
<para>
|
||||||
For all expressions and <acronym>SQL</acronym> statements used in
|
For all expressions and <acronym>SQL</acronym> statements used in
|
||||||
the function, the PL/pgSQL bytecode interpreter creates a
|
the function, the PL/pgSQL bytecode interpreter creates a
|
||||||
prepared execution plan using the SPI manager's SPI_prepare() and
|
prepared execution plan using the <acronym>SPI</acronym> manager's <function>SPI_prepare()</function> and
|
||||||
SPI_saveplan() functions. This is done the first time the individual
|
<function>SPI_saveplan()</function> functions. This is done the first time the individual
|
||||||
statement is processed in the PL/pgSQL function. Thus, a function with
|
statement is processed in the PL/pgSQL function. Thus, a function with
|
||||||
conditional code that contains many statements for which execution
|
conditional code that contains many statements for which execution
|
||||||
plans would be required, will only prepare and save those plans
|
plans would be required, will only prepare and save those plans
|
||||||
@ -107,14 +107,14 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.20 2001/02/19 19:49:52
|
|||||||
<para>
|
<para>
|
||||||
PL/pgSQL is a block oriented language. A block is defined as
|
PL/pgSQL is a block oriented language. A block is defined as
|
||||||
|
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
[DECLARE
|
<optional>DECLARE
|
||||||
<replaceable>declarations</replaceable>]
|
<replaceable>declarations</replaceable></optional>
|
||||||
BEGIN
|
BEGIN
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END;
|
END;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -141,12 +141,12 @@ END;
|
|||||||
<title>Comments</title>
|
<title>Comments</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There are two types of comments in PL/pgSQL. A double dash '--'
|
There are two types of comments in PL/pgSQL. A double dash <literal>--</literal>
|
||||||
starts a comment that extends to the end of the line. A '/*'
|
starts a comment that extends to the end of the line. A <literal>/*</literal>
|
||||||
starts a block comment that extends to the next occurrence of '*/'.
|
starts a block comment that extends to the next occurrence of <literal>*/</literal>.
|
||||||
Block comments cannot be nested, but double dash comments can be
|
Block comments cannot be nested, but double dash comments can be
|
||||||
enclosed into a block comment and a double dash can hide
|
enclosed into a block comment and a double dash can hide
|
||||||
the block comment delimiters '/*' and '*/'.
|
the block comment delimiters <literal>/*</literal> and <literal>*/</literal>.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@ -160,16 +160,16 @@ END;
|
|||||||
sub-blocks must be declared in the declarations section of a block,
|
sub-blocks must be declared in the declarations section of a block,
|
||||||
except for the loop variable of a FOR-loop iterating over a range
|
except for the loop variable of a FOR-loop iterating over a range
|
||||||
of integer values. Parameters given to a PL/pgSQL function are
|
of integer values. Parameters given to a PL/pgSQL function are
|
||||||
automatically declared with the usual identifiers $n.
|
automatically declared with the usual identifiers <literal>$1</literal>, <literal>$2</literal>, etc.
|
||||||
The declarations have the following syntax:
|
The declarations have the following syntax:
|
||||||
</para>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<replaceable>name</replaceable> [ CONSTANT ]
|
<replaceable>name</replaceable> <optional> CONSTANT </optional>
|
||||||
<replaceable>type</replaceable> [ NOT NULL ] [ DEFAULT | :=
|
<replaceable>type</replaceable> <optional> NOT NULL </optional> <optional> DEFAULT | :=
|
||||||
<replaceable>value</replaceable> ];
|
<replaceable>value</replaceable> </optional>;
|
||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
@ -182,7 +182,7 @@ END;
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The default value is evaluated every time the block is entered. So
|
The default value is evaluated every time the block is entered. So
|
||||||
assigning '<replaceable>now</replaceable>' to a variable of type
|
assigning <literal>'now'</literal> to a variable of type
|
||||||
<type>timestamp</type> causes the variable to have the
|
<type>timestamp</type> causes the variable to have the
|
||||||
time of the actual function call, not when the function was
|
time of the actual function call, not when the function was
|
||||||
precompiled into its bytecode.
|
precompiled into its bytecode.
|
||||||
@ -208,7 +208,7 @@ END;
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The fields of the rowtype inherit the table's field sizes
|
The fields of the rowtype inherit the table's field sizes
|
||||||
or precision for char() etc. data types.
|
or precision for <type>char()</type> etc. data types.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -246,7 +246,7 @@ END;
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
This aliasing is required for composite types given as arguments to
|
This aliasing is required for composite types given as arguments to
|
||||||
a function. The dot notation $1.salary as in SQL functions is not
|
a function. The dot notation $1.salary as in <acronym>SQL</acronym> functions is not
|
||||||
allowed in PL/pgSQL.
|
allowed in PL/pgSQL.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -311,16 +311,16 @@ RENAME <replaceable>oldname</replaceable> TO <replaceable>newname</replaceable>;
|
|||||||
Using the <replaceable>table.field</replaceable>%TYPE
|
Using the <replaceable>table.field</replaceable>%TYPE
|
||||||
causes PL/pgSQL to look up the attributes definitions at the
|
causes PL/pgSQL to look up the attributes definitions at the
|
||||||
first call to the function during the lifetime of a backend.
|
first call to the function during the lifetime of a backend.
|
||||||
Suppose we have a table with a char(20) attribute and some PL/pgSQL functions
|
Suppose we have a table with a <type>char(20)</type> attribute and some PL/pgSQL functions
|
||||||
that deal with its content in local variables. Now someone
|
that deal with its content in local variables. Now someone
|
||||||
decides that char(20) isn't enough, dumps the table, drops it,
|
decides that <type>char(20)</type> is not enough, dumps the table, drops it,
|
||||||
recreates it now with the attribute in question defined as
|
recreates it now with the attribute in question defined as
|
||||||
char(40) and restores the data. Ha - he forgot about the
|
<type>char(40)</type> and restores the data. Hah - he forgot about the
|
||||||
functions. The computations inside them will truncate the values
|
functions. The computations inside them will truncate the values
|
||||||
to 20 characters. But if they are defined using the
|
to 20 characters. But if they are defined using the
|
||||||
<replaceable>table.field</replaceable>%TYPE
|
<replaceable>table.field</replaceable>%TYPE
|
||||||
declarations, they will automagically handle the size change or
|
declarations, they will automagically handle the size change or
|
||||||
if the new table schema defines the attribute as text type.
|
if the new table schema defines the attribute as <type>text</type> type.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@ -332,15 +332,15 @@ RENAME <replaceable>oldname</replaceable> TO <replaceable>newname</replaceable>;
|
|||||||
<para>
|
<para>
|
||||||
All expressions used in PL/pgSQL statements are processed using
|
All expressions used in PL/pgSQL statements are processed using
|
||||||
the backend's executor. Expressions that appear to contain
|
the backend's executor. Expressions that appear to contain
|
||||||
constants may in fact require run-time evaluation (e.g. 'now' for the
|
constants may in fact require runtime evaluation (e.g., <literal>'now'</literal> for the
|
||||||
<type>timestamp</type> type) so
|
<type>timestamp</type> type) so
|
||||||
it is impossible for the PL/pgSQL parser
|
it is impossible for the PL/pgSQL parser
|
||||||
to identify real constant values other than the NULL keyword. All
|
to identify real constant values other than the NULL keyword. All
|
||||||
expressions are evaluated internally by executing a query
|
expressions are evaluated internally by executing a query
|
||||||
<programlisting>
|
<synopsis>
|
||||||
SELECT <replaceable>expression</replaceable>
|
SELECT <replaceable>expression</replaceable>
|
||||||
</programlisting>
|
</synopsis>
|
||||||
using the SPI manager. In the expression, occurrences of variable
|
using the <acronym>SPI</acronym> manager. In the expression, occurrences of variable
|
||||||
identifiers are substituted by parameters and the actual values from
|
identifiers are substituted by parameters and the actual values from
|
||||||
the variables are passed to the executor in the parameter array. All
|
the variables are passed to the executor in the parameter array. All
|
||||||
expressions used in a PL/pgSQL function are only prepared and
|
expressions used in a PL/pgSQL function are only prepared and
|
||||||
@ -379,29 +379,31 @@ CREATE FUNCTION logfunc2 (text) RETURNS timestamp AS '
|
|||||||
' LANGUAGE 'plpgsql';
|
' LANGUAGE 'plpgsql';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
do. In the case of logfunc1(), the <productname>Postgres</productname>
|
do. In the case of <function>logfunc1()</function>, the
|
||||||
main parser
|
<productname>Postgres</productname> main parser knows when
|
||||||
knows when preparing the plan for the INSERT, that the string 'now'
|
preparing the plan for the INSERT, that the string
|
||||||
should be interpreted as <type>timestamp</type> because the target field of logtable
|
<literal>'now'</literal> should be interpreted as
|
||||||
is of that type. Thus, it will make a constant from it at this time
|
<type>timestamp</type> because the target field of logtable is of
|
||||||
and this constant value is then used in all invocations of logfunc1()
|
that type. Thus, it will make a constant from it at this time and
|
||||||
during the lifetime of the backend. Needless to say that this isn't what the
|
this constant value is then used in all invocations of
|
||||||
programmer wanted.
|
<function>logfunc1()</function> during the lifetime of the
|
||||||
|
backend. Needless to say that this isn't what the programmer
|
||||||
|
wanted.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
In the case of logfunc2(), the <productname>Postgres</productname>
|
In the case of <function>logfunc2()</function>, the <productname>Postgres</productname>
|
||||||
main parser does not know
|
main parser does not know
|
||||||
what type 'now' should become and therefore it returns a data type of
|
what type <literal>'now'</literal> should become and therefore it returns a data type of
|
||||||
text containing the string 'now'. During the assignment
|
<type>text</type> containing the string <literal>'now'</literal>. During the assignment
|
||||||
to the local variable curtime, the PL/pgSQL interpreter casts this
|
to the local variable curtime, the PL/pgSQL interpreter casts this
|
||||||
string to the timestamp type by calling the text_out() and timestamp_in()
|
string to the timestamp type by calling the <function>text_out()</function> and <function>timestamp_in()</function>
|
||||||
functions for the conversion.
|
functions for the conversion.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
This type checking done by the <productname>Postgres</productname> main
|
This type checking done by the <productname>Postgres</productname> main
|
||||||
parser got implemented after PL/pgSQL was nearly done.
|
parser got implemented after PL/pgSQL was nearly done.
|
||||||
It is a difference between 6.3 and 6.4 and affects all functions
|
It is a difference between 6.3 and 6.4 and affects all functions
|
||||||
using the prepared plan feature of the SPI manager.
|
using the prepared plan feature of the <acronym>SPI</acronym> manager.
|
||||||
Using a local
|
Using a local
|
||||||
variable in the above manner is currently the only way in PL/pgSQL to get
|
variable in the above manner is currently the only way in PL/pgSQL to get
|
||||||
those values interpreted correctly.
|
those values interpreted correctly.
|
||||||
@ -433,12 +435,12 @@ CREATE FUNCTION logfunc2 (text) RETURNS timestamp AS '
|
|||||||
<para>
|
<para>
|
||||||
An assignment of a value to a variable or row/record field is
|
An assignment of a value to a variable or row/record field is
|
||||||
written as
|
written as
|
||||||
<programlisting>
|
<synopsis>
|
||||||
<replaceable>identifier</replaceable> := <replaceable>expression</replaceable>;
|
<replaceable>identifier</replaceable> := <replaceable>expression</replaceable>;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
If the expressions result data type doesn't match the variables
|
If the expressions result data type doesn't match the variables
|
||||||
data type, or the variable has a size/precision that is known
|
data type, or the variable has a size/precision that is known
|
||||||
(as for char(20)), the result value will be implicitly casted by
|
(as for <type>char(20)</type>), the result value will be implicitly cast by
|
||||||
the PL/pgSQL bytecode interpreter using the result types output- and
|
the PL/pgSQL bytecode interpreter using the result types output- and
|
||||||
the variables type input-functions. Note that this could potentially
|
the variables type input-functions. Note that this could potentially
|
||||||
result in runtime errors generated by the types input functions.
|
result in runtime errors generated by the types input functions.
|
||||||
@ -446,9 +448,9 @@ CREATE FUNCTION logfunc2 (text) RETURNS timestamp AS '
|
|||||||
<para>
|
<para>
|
||||||
An assignment of a complete selection into a record or row can
|
An assignment of a complete selection into a record or row can
|
||||||
be done by
|
be done by
|
||||||
<programlisting>
|
<synopsis>
|
||||||
SELECT INTO <replaceable>target</replaceable> <replaceable>expressions</replaceable> FROM ...;
|
SELECT INTO <replaceable>target</replaceable> <replaceable>expressions</replaceable> FROM ...;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
<replaceable>target</replaceable> can be a record, a row variable or a
|
<replaceable>target</replaceable> can be a record, a row variable or a
|
||||||
comma separated list of variables and record-/row-fields. Note that
|
comma separated list of variables and record-/row-fields. Note that
|
||||||
this is quite different from Postgres' normal interpretation of
|
this is quite different from Postgres' normal interpretation of
|
||||||
@ -463,7 +465,7 @@ SELECT INTO <replaceable>target</replaceable> <replaceable>expressions</replace
|
|||||||
grouping, sorting etc. that can be given for a SELECT statement.
|
grouping, sorting etc. that can be given for a SELECT statement.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
There is a special variable named FOUND of type bool that can be used
|
There is a special variable named FOUND of type <type>boolean</type> that can be used
|
||||||
immediately after a SELECT INTO to check if an assignment had success.
|
immediately after a SELECT INTO to check if an assignment had success.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -488,11 +490,11 @@ END IF;
|
|||||||
is to execute a SELECT query or doing an assignment (resulting
|
is to execute a SELECT query or doing an assignment (resulting
|
||||||
in a PL/pgSQL internal SELECT). But there are cases where someone
|
in a PL/pgSQL internal SELECT). But there are cases where someone
|
||||||
is not interested in the function's result.
|
is not interested in the function's result.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
PERFORM <replaceable>query</replaceable>
|
PERFORM <replaceable>query</replaceable>
|
||||||
</programlisting>
|
</synopsis>
|
||||||
executes a 'SELECT <replaceable>query</replaceable>' over the
|
executes a <literal>SELECT <replaceable>query</replaceable></literal> over the
|
||||||
SPI manager and discards the result. Identifiers like local
|
<acronym>SPI</acronym> manager and discards the result. Identifiers like local
|
||||||
variables are still substituted into parameters.
|
variables are still substituted into parameters.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -501,14 +503,13 @@ PERFORM <replaceable>query</replaceable>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Executing dynamic queries</term>
|
<term>Executing dynamic queries</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<cmdsynopsis>
|
|
||||||
<command>EXECUTE</command>
|
|
||||||
<arg choice="req"><replaceable class="command">query-string</replaceable></arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
where <replaceable>query-string</replaceable> is a string
|
<synopsis>
|
||||||
of type TEXT containing the <replaceable>query</replaceable> to be executed.
|
EXECUTE <replaceable class="command">query-string</replaceable>
|
||||||
|
</synopsis>
|
||||||
|
where <replaceable>query-string</replaceable> is a string of
|
||||||
|
type <type>text</type> containing the <replaceable>query</replaceable> to be
|
||||||
|
executed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -557,17 +558,17 @@ EXECUTE ''UPDATE tbl SET ''
|
|||||||
<term>Obtaining other results status</term>
|
<term>Obtaining other results status</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<synopsis>
|
||||||
GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> [ , ... ]
|
GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>
|
||||||
</programlisting>
|
</synopsis>
|
||||||
This command allows retrieval of system status indicators. Each
|
This command allows retrieval of system status indicators. Each
|
||||||
<replaceable>item</replaceable> is a keyword identifying a state
|
<replaceable>item</replaceable> is a keyword identifying a state
|
||||||
value to be assigned to the specified variable (which should be of
|
value to be assigned to the specified variable (which should be of
|
||||||
the right datatype to receive it). The currently available status
|
the right datatype to receive it). The currently available status
|
||||||
items are <keyword>ROW_COUNT</>, the number of rows processed by
|
items are <varname>ROW_COUNT</>, the number of rows processed by
|
||||||
the last SQL query sent down to the SQL engine; and
|
the last <acronym>SQL</acronym> query sent down to the <acronym>SQL</acronym> engine; and
|
||||||
<keyword>RESULT_OID</>, the Oid of the last row inserted by the
|
<varname>RESULT_OID</>, the Oid of the last row inserted by the
|
||||||
most recent SQL query. Note that <keyword>RESULT_OID</> is only
|
most recent <acronym>SQL</acronym> query. Note that <varname>RESULT_OID</> is only
|
||||||
useful after an INSERT query.
|
useful after an INSERT query.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -577,9 +578,9 @@ GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replace
|
|||||||
<term>Returning from the function</term>
|
<term>Returning from the function</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<synopsis>
|
||||||
RETURN <replaceable>expression</replaceable>
|
RETURN <replaceable>expression</replaceable>
|
||||||
</programlisting>
|
</synopsis>
|
||||||
The function terminates and the value of <replaceable>expression</replaceable>
|
The function terminates and the value of <replaceable>expression</replaceable>
|
||||||
will be returned to the upper executor. The return value of a function
|
will be returned to the upper executor. The return value of a function
|
||||||
cannot be undefined. If control reaches the end of the top-level block
|
cannot be undefined. If control reaches the end of the top-level block
|
||||||
@ -600,10 +601,10 @@ RETURN <replaceable>expression</replaceable>
|
|||||||
As indicated in the above examples there is a RAISE statement that
|
As indicated in the above examples there is a RAISE statement that
|
||||||
can throw messages into the <productname>Postgres</productname>
|
can throw messages into the <productname>Postgres</productname>
|
||||||
elog mechanism.
|
elog mechanism.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
RAISE <replaceable class="parameter">level</replaceable> '<replaceable class="parameter">format</replaceable>' [, <replaceable class="parameter">identifier</replaceable> [...]];
|
RAISE <replaceable class="parameter">level</replaceable> '<replaceable class="parameter">format</replaceable>' <optional>, <replaceable class="parameter">identifier</replaceable> <optional>...</optional></optional>;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
Inside the format, "<literal>%</literal>" is used as a placeholder for the
|
Inside the format, <literal>%</literal> is used as a placeholder for the
|
||||||
subsequent comma-separated identifiers. Possible levels are
|
subsequent comma-separated identifiers. Possible levels are
|
||||||
DEBUG (silently suppressed in production running databases), NOTICE
|
DEBUG (silently suppressed in production running databases), NOTICE
|
||||||
(written into the database log and forwarded to the client application)
|
(written into the database log and forwarded to the client application)
|
||||||
@ -616,15 +617,15 @@ RAISE <replaceable class="parameter">level</replaceable> '<replaceable class="pa
|
|||||||
<term>Conditionals</term>
|
<term>Conditionals</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<synopsis>
|
||||||
IF <replaceable>expression</replaceable> THEN
|
IF <replaceable>expression</replaceable> THEN
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
[ELSE
|
<optional>ELSE
|
||||||
<replaceable>statements</replaceable>]
|
<replaceable>statements</replaceable></optional>
|
||||||
END IF;
|
END IF;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
The <replaceable>expression</replaceable> must return a value that
|
The <replaceable>expression</replaceable> must return a value that
|
||||||
is a boolean or can be casted into a boolean.
|
is of type <type>boolean</type> or can be casted to a <type>boolean</type>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -636,60 +637,60 @@ Loops
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
There are multiple types of loops.
|
There are multiple types of loops.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
LOOP
|
LOOP
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
An unconditional loop that must be terminated explicitly
|
An unconditional loop that must be terminated explicitly
|
||||||
by an EXIT statement. The optional label can be used by
|
by an EXIT statement. The optional label can be used by
|
||||||
EXIT statements of nested loops to specify which level of
|
EXIT statements of nested loops to specify which level of
|
||||||
nesting should be terminated.
|
nesting should be terminated.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
WHILE <replaceable>expression</replaceable> LOOP
|
WHILE <replaceable>expression</replaceable> LOOP
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
A conditional loop that is executed as long as the evaluation
|
A conditional loop that is executed as long as the evaluation
|
||||||
of <replaceable>expression</replaceable> is true.
|
of <replaceable>expression</replaceable> is true.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
FOR <replaceable>name</replaceable> IN [ REVERSE ] <replaceable>expression</replaceable> .. <replaceable>expression</replaceable> LOOP
|
FOR <replaceable>name</replaceable> IN <optional> REVERSE </optional> <replaceable>expression</replaceable> .. <replaceable>expression</replaceable> LOOP
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
A loop that iterates over a range of integer values. The variable
|
A loop that iterates over a range of integer values. The variable
|
||||||
<replaceable>name</replaceable> is automatically created as type
|
<replaceable>name</replaceable> is automatically created as type
|
||||||
integer and exists only inside the loop. The two expressions giving
|
integer and exists only inside the loop. The two expressions giving
|
||||||
the lower and upper bound of the range are evaluated only when entering
|
the lower and upper bound of the range are evaluated only when entering
|
||||||
the loop. The iteration step is always 1.
|
the loop. The iteration step is always 1.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
FOR <replaceable>record | row</replaceable> IN <replaceable>select_clause</replaceable> LOOP
|
FOR <replaceable>record | row</replaceable> IN <replaceable>select_clause</replaceable> LOOP
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
The record or row is assigned all the rows resulting from the select
|
The record or row is assigned all the rows resulting from the select
|
||||||
clause and the loop body is executed for each row. If the loop is
|
clause and the loop body is executed for each row. If the loop is
|
||||||
terminated with an EXIT statement, the last assigned row is still
|
terminated with an EXIT statement, the last assigned row is still
|
||||||
accessible after the loop.
|
accessible after the loop.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
[<<label>>]
|
<optional><<label>></optional>
|
||||||
FOR <replaceable>record | row</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> LOOP
|
FOR <replaceable>record | row</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> LOOP
|
||||||
<replaceable>statements</replaceable>
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
This is like the previous form, except that the source SELECT
|
This is like the previous form, except that the source SELECT
|
||||||
statement is specified as a string expression, which is evaluated
|
statement is specified as a string expression, which is evaluated
|
||||||
and re-planned on each entry to the FOR loop. This allows the
|
and re-planned on each entry to the FOR loop. This allows the
|
||||||
programmer to choose the speed of a pre-planned query or the
|
programmer to choose the speed of a pre-planned query or the
|
||||||
flexibility of a dynamic query, just as with a plain EXECUTE
|
flexibility of a dynamic query, just as with a plain EXECUTE
|
||||||
statement.
|
statement.
|
||||||
<programlisting>
|
<synopsis>
|
||||||
EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replaceable> ];
|
EXIT <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>expression</replaceable> </optional>;
|
||||||
</programlisting>
|
</synopsis>
|
||||||
If no <replaceable>label</replaceable> given,
|
If no <replaceable>label</replaceable> given,
|
||||||
the innermost loop is terminated and the
|
the innermost loop is terminated and the
|
||||||
statement following END LOOP is executed next.
|
statement following END LOOP is executed next.
|
||||||
@ -727,7 +728,7 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>NEW</term>
|
<term><varname>NEW</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type RECORD; variable holding the new database row on INSERT/UPDATE
|
Data type RECORD; variable holding the new database row on INSERT/UPDATE
|
||||||
@ -737,7 +738,7 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>OLD</term>
|
<term><varname>OLD</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type RECORD; variable holding the old database row on UPDATE/DELETE
|
Data type RECORD; variable holding the old database row on UPDATE/DELETE
|
||||||
@ -747,47 +748,47 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_NAME</term>
|
<term><varname>TG_NAME</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type name; variable that contains the name of the trigger actually
|
Data type <type>name</type>; variable that contains the name of the trigger actually
|
||||||
fired.
|
fired.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_WHEN</term>
|
<term><varname>TG_WHEN</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type text; a string of either 'BEFORE' or 'AFTER' depending on the
|
Data type <type>text</type>; a string of either <literal>'BEFORE'</literal> or <literal>'AFTER'</literal> depending on the
|
||||||
triggers definition.
|
triggers definition.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_LEVEL</term>
|
<term><varname>TG_LEVEL</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type text; a string of either 'ROW' or 'STATEMENT' depending on the
|
Data type <type>text</type>; a string of either <literal>'ROW'</literal> or <literal>'STATEMENT'</literal> depending on the
|
||||||
triggers definition.
|
triggers definition.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_OP</term>
|
<term><varname>TG_OP</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type text; a string of 'INSERT', 'UPDATE' or 'DELETE' telling
|
Data type <type>text</type>; a string of <literal>'INSERT'</literal>, <literal>'UPDATE'</literal>, or <literal>'DELETE'</literal> telling
|
||||||
for which operation the trigger is actually fired.
|
for which operation the trigger is actually fired.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_RELID</term>
|
<term><varname>TG_RELID</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type oid; the object ID of the table that caused the
|
Data type oid; the object ID of the table that caused the
|
||||||
@ -797,7 +798,7 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_RELNAME</term>
|
<term><varname>TG_RELNAME</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type name; the name of the table that caused the trigger
|
Data type name; the name of the table that caused the trigger
|
||||||
@ -807,7 +808,7 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_NARGS</term>
|
<term><varname>TG_NARGS</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type integer; the number of arguments given to the trigger
|
Data type integer; the number of arguments given to the trigger
|
||||||
@ -817,10 +818,10 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>TG_ARGV[]</term>
|
<term><varname>TG_ARGV[]</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Data type array of text; the arguments from the CREATE TRIGGER statement.
|
Data type array of <type>text</type>; the arguments from the CREATE TRIGGER statement.
|
||||||
The index counts from 0 and can be given as an expression. Invalid
|
The index counts from 0 and can be given as an expression. Invalid
|
||||||
indices (< 0 or >= tg_nargs) result in a NULL value.
|
indices (< 0 or >= tg_nargs) result in a NULL value.
|
||||||
</para>
|
</para>
|
||||||
@ -880,24 +881,24 @@ EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replac
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Here are only a few functions to demonstrate how easy PL/pgSQL
|
Here are only a few functions to demonstrate how easy it is to write PL/pgSQL
|
||||||
functions can be written. For more complex examples the programmer
|
functions. For more complex examples the programmer
|
||||||
might look at the regression test for PL/pgSQL.
|
might look at the regression test for PL/pgSQL.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
One painful detail of writing functions in PL/pgSQL is the handling
|
One painful detail in writing functions in PL/pgSQL is the handling
|
||||||
of single quotes. The function's source text on CREATE FUNCTION must
|
of single quotes. The function's source text in the <command>CREATE FUNCTION</command> command must
|
||||||
be a literal string. Single quotes inside of literal strings must be
|
be a literal string. Single quotes inside of literal strings must be
|
||||||
either doubled or quoted with a backslash. We are still looking for
|
either doubled or quoted with a backslash. We are still looking for
|
||||||
an elegant alternative. In the meantime, doubling the single quotes
|
an elegant alternative. In the meantime, doubling the single quotes
|
||||||
as in the examples below should be used. Any solution for this
|
as in the examples below should be used. Any solution for this
|
||||||
in future versions of <productname>Postgres</productname> will be
|
in future versions of <productname>Postgres</productname> will be
|
||||||
upward compatible.
|
forward compatible.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2>
|
<example>
|
||||||
<title>Some Simple PL/pgSQL Functions</title>
|
<title>A Simple PL/pgSQL Functions</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following two PL/pgSQL functions are identical to their
|
The following two PL/pgSQL functions are identical to their
|
||||||
@ -920,17 +921,17 @@ CREATE FUNCTION concat_text (text, text) RETURNS text AS '
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</example>
|
||||||
|
|
||||||
<sect2>
|
<example>
|
||||||
<title>PL/pgSQL Function on Composite Type</title>
|
<title>A PL/pgSQL Function on a Composite Type</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Again it is the PL/pgSQL equivalent to the example from
|
Again, this is the PL/pgSQL equivalent to the example from
|
||||||
The C functions.
|
the C functions.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE FUNCTION c_overpaid (EMP, integer) RETURNS bool AS '
|
CREATE FUNCTION c_overpaid (EMP, integer) RETURNS boolean AS '
|
||||||
DECLARE
|
DECLARE
|
||||||
emprec ALIAS FOR $1;
|
emprec ALIAS FOR $1;
|
||||||
sallim ALIAS FOR $2;
|
sallim ALIAS FOR $2;
|
||||||
@ -944,13 +945,13 @@ CREATE FUNCTION c_overpaid (EMP, integer) RETURNS bool AS '
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</example>
|
||||||
|
|
||||||
<sect2>
|
<example>
|
||||||
<title>PL/pgSQL Trigger Procedure</title>
|
<title>A PL/pgSQL Trigger Procedure</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This trigger ensures, that any time a row is inserted or updated
|
This trigger ensures that any time a row is inserted or updated
|
||||||
in the table, the current user name and time are stamped into the
|
in the table, the current user name and time are stamped into the
|
||||||
row. And it ensures that an employees name is given and that the
|
row. And it ensures that an employees name is given and that the
|
||||||
salary is a positive value.
|
salary is a positive value.
|
||||||
@ -988,7 +989,7 @@ CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
|
|||||||
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
|
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</example>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user