Small adjustments in markup getting ready for hardcopy release.
Jan did a nice job of initial markup so it was pretty easy!
This commit is contained in:
parent
0061719728
commit
20a0713264
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,8 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
Since version 6.3 <ProductName>Postgres</ProductName> supports
|
Beginning with the release of version 6.3,
|
||||||
|
<ProductName>Postgres</ProductName> supports
|
||||||
the definition of procedural languages.
|
the definition of procedural languages.
|
||||||
In the case of a function or trigger
|
In the case of a function or trigger
|
||||||
procedure defined in a procedural language, the database has
|
procedure defined in a procedural language, the database has
|
||||||
@ -25,13 +26,17 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<Sect1>
|
<Sect1>
|
||||||
<Title>Installing procedural languages</Title>
|
<Title>Installing Procedural Languages</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
<Procedure>
|
<Procedure>
|
||||||
<Title>
|
<Title>
|
||||||
A procedural language is installed in the database in three steps.
|
Procedural Language Installation
|
||||||
</Title>
|
</Title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A procedural language is installed in the database in three steps.
|
||||||
|
|
||||||
<Step Performance="Required">
|
<Step Performance="Required">
|
||||||
<Para>
|
<Para>
|
||||||
The shared object for the language handler
|
The shared object for the language handler
|
||||||
@ -63,7 +68,7 @@
|
|||||||
<Para>
|
<Para>
|
||||||
The PL must be declared with the command
|
The PL must be declared with the command
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
CREATE [TRUSTED] PROCEDURAL LANGUAGE '<Replaceable>language-name</Replaceable>'
|
CREATE [ TRUSTED ] PROCEDURAL LANGUAGE '<Replaceable>language-name</Replaceable>'
|
||||||
HANDLER <Replaceable>handler_function_name</Replaceable>
|
HANDLER <Replaceable>handler_function_name</Replaceable>
|
||||||
LANCOMPILER '<Replaceable>description</Replaceable>';
|
LANCOMPILER '<Replaceable>description</Replaceable>';
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
@ -153,7 +158,7 @@
|
|||||||
<Title>Overview</Title>
|
<Title>Overview</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
The design rules of PL/pgSQL where to create a loadable procedural
|
The design goals of PL/pgSQL were to create a loadable procedural
|
||||||
language that
|
language that
|
||||||
<ItemizedList>
|
<ItemizedList>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
@ -178,7 +183,7 @@
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
can be defined trusted,
|
can be defined to be trusted by the server,
|
||||||
</Para>
|
</Para>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
@ -228,7 +233,7 @@
|
|||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
The PL/pgSQL language is case insensitive. All keywords and
|
The PL/pgSQL language is case insensitive. All keywords and
|
||||||
identifiers can be used in upper-/lowercase mixed.
|
identifiers can be used in mixed upper- and lowercase.
|
||||||
</Para>
|
</Para>
|
||||||
<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
|
||||||
@ -236,9 +241,9 @@
|
|||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
[<<label>>]
|
[<<label>>]
|
||||||
[DECLARE
|
[DECLARE
|
||||||
-- declarations]
|
<replaceable>declarations</replaceable>]
|
||||||
BEGIN
|
BEGIN
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
END;
|
END;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
|
|
||||||
@ -291,7 +296,7 @@
|
|||||||
|
|
||||||
<VarListEntry>
|
<VarListEntry>
|
||||||
<Term>
|
<Term>
|
||||||
<Replaceable>name</Replaceable> [CONSTANT] <Replaceable>type</Replaceable> [NOT NULL] [DEFAULT | := <Replaceable>value</Replaceable>];
|
<Replaceable>name</Replaceable> [ CONSTANT ] <Replaceable>type</Replaceable> [ NOT NULL ] [ DEFAULT | := <Replaceable>value</Replaceable> ];
|
||||||
</Term>
|
</Term>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
@ -314,7 +319,7 @@
|
|||||||
|
|
||||||
<VarListEntry>
|
<VarListEntry>
|
||||||
<Term>
|
<Term>
|
||||||
<Replaceable>name</Replaceable> <Replaceable>class</Replaceable>%ROWTYPE;
|
<Replaceable>name</Replaceable> <Replaceable>class</Replaceable>%ROWTYPE;
|
||||||
</Term>
|
</Term>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
@ -395,7 +400,7 @@ RENAME <Replaceable>oldname</Replaceable> TO <Replaceable>newname</Replaceable>;
|
|||||||
<!-- **** PL/pgSQL data types **** -->
|
<!-- **** PL/pgSQL data types **** -->
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Data types</Title>
|
<Title>Data Types</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
The type of a varible can be any of the existing basetypes of
|
The type of a varible can be any of the existing basetypes of
|
||||||
@ -411,19 +416,20 @@ RENAME <Replaceable>oldname</Replaceable> TO <Replaceable>newname</Replaceable>;
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
<Replaceable>variable</Replaceable>%TYPE
|
<Replaceable>variable</Replaceable>%TYPE
|
||||||
</Para>
|
</Para>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
<Replaceable>class.field</Replaceable>%TYPE
|
<Replaceable>class.field</Replaceable>%TYPE
|
||||||
</Para>
|
</Para>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</ItemizedList>
|
</ItemizedList>
|
||||||
</Para>
|
</Para>
|
||||||
<Para>
|
<Para>
|
||||||
<Replaceable>variable</Replaceable> is the name of a previously in the
|
<Replaceable>variable</Replaceable> is the name of a variable,
|
||||||
same function declared variable that is visible at this point.
|
previously declared in the
|
||||||
|
same function, that is visible at this point.
|
||||||
</Para>
|
</Para>
|
||||||
<Para>
|
<Para>
|
||||||
<Replaceable>class</Replaceable> is the name of an existing table
|
<Replaceable>class</Replaceable> is the name of an existing table
|
||||||
@ -431,7 +437,7 @@ RENAME <Replaceable>oldname</Replaceable> TO <Replaceable>newname</Replaceable>;
|
|||||||
an attribute.
|
an attribute.
|
||||||
</Para>
|
</Para>
|
||||||
<Para>
|
<Para>
|
||||||
Using the <Replaceable>class.field</Replaceable>%TYPE
|
Using the <Replaceable>class.field</Replaceable>%TYPE
|
||||||
causes PL/pgSQL to lookup the attributes definitions at the
|
causes PL/pgSQL to lookup the attributes definitions at the
|
||||||
first call to the funciton during the lifetime of a backend.
|
first call to the funciton during the lifetime of a backend.
|
||||||
Have a table with a char(20) attribute and some PL/pgSQL functions
|
Have a table with a char(20) attribute and some PL/pgSQL functions
|
||||||
@ -441,7 +447,7 @@ RENAME <Replaceable>oldname</Replaceable> TO <Replaceable>newname</Replaceable>;
|
|||||||
char(40) and restores the data. Ha - he forgot about the
|
char(40) and restores the data. Ha - he forgot about the
|
||||||
funcitons. The computations inside them will truncate the values
|
funcitons. 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>class.field</Replaceable>%TYPE
|
<Replaceable>class.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 text type.
|
||||||
</Para>
|
</Para>
|
||||||
@ -454,22 +460,24 @@ 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 backends executor. Since even a constant looking expression
|
the backends executor. Expressions which appear to contain
|
||||||
can have a totally different meaning for a particular data type
|
constants may in fact require run-time evaluation (e.g. 'now' for the
|
||||||
(as 'now' for datetime), it is impossible for the PL/pgSQL parser
|
datetime type) so
|
||||||
|
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>
|
<ProgramListing>
|
||||||
SELECT <Replaceable>expression</Replaceable>
|
SELECT <Replaceable>expression</Replaceable>
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
over the SPI manager. In the expression, occurences of variable
|
using the SPI manager. In the expression, occurences 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
|
||||||
saved once.
|
saved once.
|
||||||
</Para>
|
</Para>
|
||||||
<Para>
|
<Para>
|
||||||
The type checking done by the postgres main parser has some side
|
The type checking done by the <productname>Postgres</productname>
|
||||||
|
main parser has some side
|
||||||
effects to the interpretation of constant values. In detail there
|
effects to the interpretation of constant values. In detail there
|
||||||
is a difference between what the two functions
|
is a difference between what the two functions
|
||||||
|
|
||||||
@ -553,7 +561,7 @@ Assignment
|
|||||||
</Term>
|
</Term>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Para>
|
<Para>
|
||||||
An assignment of a value to a varable or row/record field is
|
An assignment of a value to a variable or row/record field is
|
||||||
written as
|
written as
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
<Replaceable>identifier</Replaceable> := <Replaceable>expression</Replaceable>;
|
<Replaceable>identifier</Replaceable> := <Replaceable>expression</Replaceable>;
|
||||||
@ -587,7 +595,7 @@ Assignment
|
|||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
SELECT * INTO myrec FROM EMP WHERE empname = myname;
|
SELECT * INTO myrec FROM EMP WHERE empname = myname;
|
||||||
IF NOT FOUND THEN
|
IF NOT FOUND THEN
|
||||||
RAISE EXCEPTION ''employee % not found'', myname;
|
RAISE EXCEPTION ''employee % not found'', myname;
|
||||||
END IF;
|
END IF;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
|
|
||||||
@ -650,11 +658,11 @@ Aborting and messages
|
|||||||
can throw messages into the <ProductName>Postgres</ProductName>
|
can throw messages into the <ProductName>Postgres</ProductName>
|
||||||
elog mechanism.
|
elog mechanism.
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
RAISE level ''format'' [, identifier [...]];
|
RAISE <replaceable class="parameter">level</replaceable> ''<replaceable class="parameter">format</replaceable>'' [, <replaceable class="parameter">identifier</replaceable> [...]];
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
Inside the format, % is used as a placeholder for the
|
Inside the format, <quote>%</quote> is used as a placeholder for the
|
||||||
following, comma separated identifiers. Possible levels are
|
subsequent comma-separated identifiers. Possible levels are
|
||||||
DEBUG (silently suppressed in productional 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)
|
||||||
and EXCEPTION (written into the database log and aborting the transaction).
|
and EXCEPTION (written into the database log and aborting the transaction).
|
||||||
</Para>
|
</Para>
|
||||||
@ -669,9 +677,9 @@ Conditionals
|
|||||||
<Para>
|
<Para>
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
IF <Replaceable>expression</Replaceable> THEN
|
IF <Replaceable>expression</Replaceable> THEN
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
[ELSE
|
[ELSE
|
||||||
-- statements]
|
<replaceable>statements</replaceable>]
|
||||||
END IF;
|
END IF;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
The <Replaceable>expression</Replaceable> must return a value that
|
The <Replaceable>expression</Replaceable> must return a value that
|
||||||
@ -690,7 +698,7 @@ Loops
|
|||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
[<<label>>]
|
[<<label>>]
|
||||||
LOOP
|
LOOP
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
An unconditional loop that must be terminated explicitly
|
An unconditional loop that must be terminated explicitly
|
||||||
@ -700,15 +708,15 @@ Loops
|
|||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
[<<label>>]
|
[<<label>>]
|
||||||
WHILE <Replaceable>expression</Replaceable> LOOP
|
WHILE <Replaceable>expression</Replaceable> LOOP
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
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>
|
<ProgramListing>
|
||||||
[<<label>>]
|
[<<label>>]
|
||||||
FOR <Replaceable>name</Replaceable> IN [REVERSE] <Replaceable>expression</Replaceable> .. <Replaceable>expression</Replaceable> LOOP
|
FOR <Replaceable>name</Replaceable> IN [ REVERSE ] <Replaceable>expression</Replaceable> .. <Replaceable>expression</Replaceable> LOOP
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
A loop that iterates over a range of integer values. The variable
|
A loop that iterates over a range of integer values. The variable
|
||||||
@ -719,7 +727,7 @@ Loops
|
|||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
[<<label>>]
|
[<<label>>]
|
||||||
FOR <Replaceable>record | row</Replaceable> IN <Replaceable>select_clause</Replaceable> LOOP
|
FOR <Replaceable>record | row</Replaceable> IN <Replaceable>select_clause</Replaceable> LOOP
|
||||||
-- statements
|
<replaceable>statements</replaceable>
|
||||||
END LOOP;
|
END LOOP;
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
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
|
||||||
@ -727,10 +735,12 @@ Loops
|
|||||||
with an EXIT statement, the last assigned row is still accessible
|
with an EXIT statement, the last assigned row is still accessible
|
||||||
after the loop.
|
after the loop.
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
EXIT [label] [WHEN <Replaceable>expression</Replaceable>];
|
EXIT [ <Replaceable>label</Replaceable> ] [ WHEN <Replaceable>expression</Replaceable> ];
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
If no label given, the innermost loop is terminated and the
|
If no <Replaceable>label</Replaceable> given,
|
||||||
statement following END LOOP is executed next. If label is given, it
|
the innermost loop is terminated and the
|
||||||
|
statement following END LOOP is executed next.
|
||||||
|
If <Replaceable>label</Replaceable> is given, it
|
||||||
must be the label of the current or an upper level of nested loop
|
must be the label of the current or an upper level of nested loop
|
||||||
blocks. Then the named loop or block is terminated and control
|
blocks. Then the named loop or block is terminated and control
|
||||||
continues with the statement after the loops/blocks corresponding
|
continues with the statement after the loops/blocks corresponding
|
||||||
@ -746,7 +756,7 @@ Loops
|
|||||||
<!-- **** PL/pgSQL trigger procedures **** -->
|
<!-- **** PL/pgSQL trigger procedures **** -->
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Trigger procedures</Title>
|
<Title>Trigger Procedures</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
PL/pgSQL can be used to define trigger procedures. They are created
|
PL/pgSQL can be used to define trigger procedures. They are created
|
||||||
@ -956,7 +966,7 @@ upward compatible.
|
|||||||
</Para>
|
</Para>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Some simple PL/pgSQL functions</Title>
|
<Title>Some 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
|
||||||
@ -982,7 +992,7 @@ upward compatible.
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>PL/pgSQL function on composite type</Title>
|
<Title>PL/pgSQL Function on Composite Type</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
Again it is the PL/pgSQL equivalent to the example from
|
Again it is the PL/pgSQL equivalent to the example from
|
||||||
@ -1006,7 +1016,7 @@ upward compatible.
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>PL/pgSQL trigger procedure</Title>
|
<Title>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
|
||||||
@ -1028,12 +1038,12 @@ upward compatible.
|
|||||||
RAISE EXCEPTION ''empname cannot be NULL value'';
|
RAISE EXCEPTION ''empname cannot be NULL value'';
|
||||||
END IF;
|
END IF;
|
||||||
IF NEW.salary ISNULL THEN
|
IF NEW.salary ISNULL THEN
|
||||||
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname;
|
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Who works for us when she must pay for?
|
-- Who works for us when she must pay for?
|
||||||
IF NEW.salary < 0 THEN
|
IF NEW.salary < 0 THEN
|
||||||
RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
|
RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Remember who changed the payroll when
|
-- Remember who changed the payroll when
|
||||||
@ -1099,8 +1109,8 @@ upward compatible.
|
|||||||
<Para>
|
<Para>
|
||||||
The shared object for the PL/Tcl call handler is automatically built
|
The shared object for the PL/Tcl call handler is automatically built
|
||||||
and installed in the <ProductName>Postgres</ProductName>
|
and installed in the <ProductName>Postgres</ProductName>
|
||||||
owners library directory if the Tcl/Tk support is specified
|
library directory if the Tcl/Tk support is specified
|
||||||
in the configure run.
|
in the configuration step of the installation procedure.
|
||||||
</Para>
|
</Para>
|
||||||
</Sect2>
|
</Sect2>
|
||||||
|
|
||||||
@ -1110,7 +1120,7 @@ upward compatible.
|
|||||||
<Title>Description</Title>
|
<Title>Description</Title>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title><ProductName>Postgres</ProductName> functions and Tcl procedure names</Title>
|
<Title><ProductName>Postgres</ProductName> Functions and Tcl Procedure Names</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
In <ProductName>Postgres</ProductName>, one and the
|
In <ProductName>Postgres</ProductName>, one and the
|
||||||
@ -1126,7 +1136,7 @@ upward compatible.
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Defining functions in PL/Tcl</Title>
|
<Title>Defining Functions in PL/Tcl</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
To create a function in the PL/Tcl language, use the known syntax
|
To create a function in the PL/Tcl language, use the known syntax
|
||||||
@ -1172,7 +1182,7 @@ upward compatible.
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Global data in PL/Tcl</Title>
|
<Title>Global Data in PL/Tcl</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
Sometimes (especially when using the SPI functions described later) it
|
Sometimes (especially when using the SPI functions described later) it
|
||||||
@ -1188,7 +1198,7 @@ upward compatible.
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Trigger procedures in PL/Tcl</Title>
|
<Title>Trigger Procedures in PL/Tcl</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
Trigger procedures are defined in <ProductName>Postgres</ProductName>
|
Trigger procedures are defined in <ProductName>Postgres</ProductName>
|
||||||
@ -1366,7 +1376,7 @@ $args
|
|||||||
</Sect3>
|
</Sect3>
|
||||||
|
|
||||||
<Sect3>
|
<Sect3>
|
||||||
<Title>Database access from PL/Tcl</Title>
|
<Title>Database Access from PL/Tcl</Title>
|
||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
The following commands are available to access the database from
|
The following commands are available to access the database from
|
||||||
@ -1420,7 +1430,7 @@ quote <Replaceable>string</Replaceable>
|
|||||||
and has to be written as
|
and has to be written as
|
||||||
|
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
"SELECT '[quote $val]' AS ret"
|
"SELECT '[ quote $val ]' AS ret"
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
</Para>
|
</Para>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -1516,13 +1526,13 @@ spi_exec ?-count <Replaceable>n</Replaceable>? ?-array <Replaceable>name</Replac
|
|||||||
|
|
||||||
<ProgramListing>
|
<ProgramListing>
|
||||||
CREATE FUNCTION t1_count(int4, int4) RETURNS int4 AS '
|
CREATE FUNCTION t1_count(int4, int4) RETURNS int4 AS '
|
||||||
if {![info exists GD(plan)]} {
|
if {![ info exists GD(plan) ]} {
|
||||||
# prepare the saved plan on the first call
|
# prepare the saved plan on the first call
|
||||||
set GD(plan) [spi_prepare \\
|
set GD(plan) [ spi_prepare \\
|
||||||
"SELECT count(*) AS cnt FROM t1 WHERE num >= \\$1 AND num <= \\$2" \\
|
"SELECT count(*) AS cnt FROM t1 WHERE num >= \\$1 AND num <= \\$2" \\
|
||||||
int4]
|
int4 ]
|
||||||
}
|
}
|
||||||
spi_execp -count 1 $GD(plan) [list $1 $2]
|
spi_execp -count 1 $GD(plan) [ list $1 $2 ]
|
||||||
return $cnt
|
return $cnt
|
||||||
' LANGUAGE 'pltcl';
|
' LANGUAGE 'pltcl';
|
||||||
</ProgramListing>
|
</ProgramListing>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user