1
1
<!--
2
- $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.18 2001/01/20 20:59:29 petere Exp $
2
+ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.19 2001/02/10 05:32:33 tgl Exp $
3
3
-->
4
4
5
5
<chapter id="plsql">
@@ -54,26 +54,35 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.18 2001/01/20 20:59:29
54
54
</itemizedlist>
55
55
</para>
56
56
<para>
57
- The PL/pgSQL call handler parses the functions source text and
58
- produces an internal binary instruction tree on the first time the
57
+ The PL/pgSQL call handler parses the function's source text and
58
+ produces an internal binary instruction tree the first time the
59
59
function is called. The produced bytecode is identified
60
- in the call handler by the object ID of the function. This ensures,
60
+ in the call handler by the object ID of the function. This ensures
61
61
that changing a function by a DROP/CREATE sequence will take effect
62
62
without establishing a new database connection.
63
63
</para>
64
64
<para>
65
65
For all expressions and <acronym>SQL</acronym> statements used in
66
66
the function, the PL/pgSQL bytecode interpreter creates a
67
- prepared execution plan using the SPI managers SPI_prepare() and
68
- SPI_saveplan() functions. This is done the first time, the individual
67
+ prepared execution plan using the SPI manager's SPI_prepare() and
68
+ SPI_saveplan() functions. This is done the first time the individual
69
69
statement is processed in the PL/pgSQL function. Thus, a function with
70
70
conditional code that contains many statements for which execution
71
71
plans would be required, will only prepare and save those plans
72
- that are really used during the entire lifetime of the database
72
+ that are really used during the lifetime of the database
73
73
connection.
74
74
</para>
75
75
<para>
76
- Except for input-/output-conversion and calculation functions
76
+ Because PL/pgSQL saves execution plans in this way, queries that appear
77
+ directly in a PL/pgSQL function must refer to the same tables and fields
78
+ on every execution; that is, you cannot use a parameter as the name of
79
+ a table or field in a query. To get around
80
+ this restriction, you can construct dynamic queries using the PL/pgSQL
81
+ EXECUTE statement --- at the price of constructing a new query plan
82
+ on every execution.
83
+ </para>
84
+ <para>
85
+ Except for input/output conversion and calculation functions
77
86
for user defined types, anything that can be defined in C language
78
87
functions can also be done with PL/pgSQL. It is possible to
79
88
create complex conditional computation functions and later use
@@ -118,11 +127,13 @@ END;
118
127
</para>
119
128
120
129
<para>
121
- It is important not to misunderstand the meaning of BEGIN/END for
122
- grouping statements in PL/pgSQL and the database commands for
123
- transaction control. Functions and trigger procedures cannot
124
- start or commit transactions and <productname>Postgres</productname>
125
- does not have nested transactions.
130
+ It is important not to confuse the use of BEGIN/END for
131
+ grouping statements in PL/pgSQL with the database commands for
132
+ transaction control. PL/pgSQL's BEGIN/END are only for grouping;
133
+ they do not start or end a transaction. Functions and trigger procedures
134
+ are always executed within a transaction established by an outer query
135
+ --- they cannot start or commit transactions, since
136
+ <productname>Postgres</productname> does not have nested transactions.
126
137
</para>
127
138
</sect2>
128
139
146
157
147
158
<para>
148
159
All variables, rows and records used in a block or its
149
- sub-blocks must be declared in the declarations section of a block
150
- except for the loop variable of a FOR loop iterating over a range
160
+ sub-blocks must be declared in the declarations section of a block,
161
+ except for the loop variable of a FOR- loop iterating over a range
151
162
of integer values. Parameters given to a PL/pgSQL function are
152
163
automatically declared with the usual identifiers $n.
153
164
The declarations have the following syntax:
@@ -439,7 +450,11 @@ CREATE FUNCTION logfunc2 (text) RETURNS timestamp AS '
439
450
SELECT INTO <replaceable>target</replaceable> <replaceable>expressions</replaceable> FROM ...;
440
451
</programlisting>
441
452
<replaceable>target</replaceable> can be a record, a row variable or a
442
- comma separated list of variables and record-/row-fields.
453
+ comma separated list of variables and record-/row-fields. Note that
454
+ this is quite different from Postgres' normal interpretation of
455
+ SELECT INTO, which is that the INTO target is a newly created table.
456
+ (If you want to create a table from a SELECT result inside a PL/pgSQL
457
+ function, use the equivalent syntax CREATE TABLE AS SELECT.)
443
458
</para>
444
459
<para>
445
460
if a row or a variable list is used as target, the selected values
@@ -506,10 +521,12 @@ PERFORM <replaceable>query</replaceable>
506
521
within the procedure to perform actions on variable tables and
507
522
fields.
508
523
</para>
509
-
524
+
510
525
<para>
511
- The results from SELECT queries are discarded by EXECUTE unless
512
- SELECT INTO is used to save the results into a table.
526
+ The results from SELECT queries are discarded by EXECUTE, and
527
+ SELECT INTO is not currently supported within EXECUTE. So, the
528
+ only way to extract a result from a dynamically-created SELECT
529
+ is to use the FOR ... EXECUTE form described later.
513
530
</para>
514
531
515
532
<para>
@@ -531,7 +548,7 @@ EXECUTE ''UPDATE tbl SET ''
531
548
<function>quote_literal()</function>. Both take the
532
549
appropriate steps to return the input text enclosed in single
533
550
or double quotes and with any embedded special characters
534
- intact .
551
+ properly escaped .
535
552
</para>
536
553
</listitem>
537
554
</varlistentry>
@@ -587,7 +604,7 @@ IF <replaceable>expression</replaceable> THEN
587
604
END IF;
588
605
</programlisting>
589
606
The <replaceable>expression</replaceable> must return a value that
590
- at least can be casted into a boolean type .
607
+ is a boolean or can be casted into a boolean.
591
608
</para>
592
609
</listitem>
593
610
</varlistentry>
@@ -635,9 +652,21 @@ FOR <replaceable>record | row</replaceable> IN <replaceable>select_clause</repla
635
652
END LOOP;
636
653
</programlisting>
637
654
The record or row is assigned all the rows resulting from the select
638
- clause and the statements executed for each. If the loop is terminated
639
- with an EXIT statement, the last assigned row is still accessible
640
- after the loop.
655
+ clause and the loop body is executed for each row. If the loop is
656
+ terminated with an EXIT statement, the last assigned row is still
657
+ accessible after the loop.
658
+ <programlisting>
659
+ [<<label>>]
660
+ FOR <replaceable>record | row</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> LOOP
661
+ <replaceable>statements</replaceable>
662
+ END LOOP;
663
+ </programlisting>
664
+ This is like the previous form, except that the source SELECT
665
+ statement is specified as a string expression, which is evaluated
666
+ and re-planned on each entry to the FOR loop. This allows the
667
+ programmer to choose the speed of a pre-planned query or the
668
+ flexibility of a dynamic query, just as with a plain EXECUTE
669
+ statement.
641
670
<programlisting>
642
671
EXIT [ <replaceable>label</replaceable> ] [ WHEN <replaceable>expression</replaceable> ];
643
672
</programlisting>
0 commit comments