File: plpgsql-statements.html

package info (click to toggle)
pgadmin3 1.4.3-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 29,796 kB
  • ctags: 10,758
  • sloc: cpp: 55,356; sh: 6,164; ansic: 1,520; makefile: 576; sql: 482; xml: 100; perl: 18
file content (380 lines) | stat: -rw-r--r-- 20,114 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>36.6.Basic Statements</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css">
<link rev="made" href="pgsql-docs@postgresql.org">
<meta name="generator" content="DocBook XSL Stylesheets V1.70.0">
<link rel="start" href="index.html" title="PostgreSQL 8.1.4 Documentation">
<link rel="up" href="plpgsql.html" title="Chapter36.PL/pgSQL - SQL Procedural Language">
<link rel="prev" href="plpgsql-expressions.html" title="36.5.Expressions">
<link rel="next" href="plpgsql-control-structures.html" title="36.7.Control Structures">
<link rel="copyright" href="ln-legalnotice.html" title="Legal Notice">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="plpgsql-statements"></a>36.6.Basic Statements</h2></div></div></div>
<p>    In this section and the following ones, we describe all the statement
    types that are explicitly understood by
    <span class="application">PL/pgSQL</span>.
    Anything not recognized as one of these statement types is presumed
    to be an SQL command and is sent to the main database engine to execute
    (after substitution of any <span class="application">PL/pgSQL</span> variables
    used in the statement).  Thus,
    for example, the SQL commands <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
    <code class="command">DELETE</code> may be considered to be statements of
    <span class="application">PL/pgSQL</span>, but they are not specifically
    listed here.
   </p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-statements-assignment"></a>36.6.1.Assignment</h3></div></div></div>
<p>     An assignment of a value to a variable or row/record field is
     written as:
</p>
<pre class="synopsis"><em class="replaceable"><code>identifier</code></em> := <em class="replaceable"><code>expression</code></em>;</pre>
<p>
     As explained above, the expression in such a statement is evaluated
     by means of an SQL <code class="command">SELECT</code> command sent to the main
     database engine.  The expression must yield a single value.
    </p>
<p>     If the expression's result data type doesn't match the variable's
     data type, or the variable has a specific size/precision
     (like <code class="type">char(20)</code>), the result value will be implicitly
     converted by the <span class="application">PL/pgSQL</span> interpreter using
     the result type's output-function and 
     the variable type's input-function. Note that this could potentially
     result in run-time errors generated by the input function, if the
     string form of the result value is not acceptable to the input function.
    </p>
<p>     Examples:
</p>
<pre class="programlisting">user_id := 20;
tax := subtotal * 0.06;</pre>
<p>
    </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-select-into"></a>36.6.2.<code class="command">SELECT INTO</code></h3></div></div></div>
<a name="id723033"></a><p>     The result of a <code class="command">SELECT</code> command yielding multiple columns (but
     only one row) can be assigned to a record variable, row-type
     variable, or list of scalar variables.  This is done by:

</p>
<pre class="synopsis">SELECT INTO <em class="replaceable"><code>target</code></em> <em class="replaceable"><code>select_expressions</code></em> FROM ...;</pre>
<p>

     where <em class="replaceable"><code>target</code></em> can be a record variable, a row
     variable, or a comma-separated list of simple variables and
     record/row fields.  The <em class="replaceable"><code>select_expressions</code></em>
     and the remainder of the command are the same as in regular SQL.
    </p>
<p>     Note that this is quite different from
     <span class="productname">PostgreSQL</span>'s normal interpretation of
     <code class="command">SELECT INTO</code>, where the <code class="literal">INTO</code> target
     is a newly created table.  If you want to create a table from a
     <code class="command">SELECT</code> result inside a
     <span class="application">PL/pgSQL</span> function, use the syntax
     <code class="command">CREATE TABLE ... AS SELECT</code>.
    </p>
<p>     If a row or a variable list is used as target, the selected values
     must exactly match the structure of the target, or a run-time error
     occurs.  When a record variable is the target, it automatically
     configures itself to the row type of the query result columns.
    </p>
<p>     Except for the <code class="literal">INTO</code> clause, the <code class="command">SELECT</code>
     statement is the same as a normal SQL <code class="command">SELECT</code> command
     and can use its full power.
    </p>
<p>     The <code class="literal">INTO</code> clause can appear almost anywhere in the
     <code class="command">SELECT</code> statement.  Customarily it is written
     either just after <code class="literal">SELECT</code> as shown above, or
     just before <code class="literal">FROM</code> [mdash ] that is, either just before
     or just after the list of <em class="replaceable"><code>select_expressions</code></em>.
    </p>
<p>     If the query returns zero rows, null values are assigned to the
     target(s).  If the query returns multiple rows, the first
     row is assigned to the target(s) and the rest are discarded.
     (Note that &#8220;<span class="quote">the first row</span>&#8221; is not well-defined unless you've
     used <code class="literal">ORDER BY</code>.)
    </p>
<p>     You can check the special <code class="literal">FOUND</code> variable (see
     <a href="plpgsql-statements.html#plpgsql-statements-diagnostics" title="36.6.6.Obtaining the Result Status">Section36.6.6, &#8220;Obtaining the Result Status&#8221;</a>) after a
     <code class="command">SELECT INTO</code> statement to determine whether the
     assignment was successful, that is, at least one row was was returned by
     the query. For example:

</p>
<pre class="programlisting">SELECT INTO myrec * FROM emp WHERE empname = myname;
IF NOT FOUND THEN
    RAISE EXCEPTION 'employee % not found', myname;
END IF;</pre>
<p>
    </p>
<p>     To test for whether a record/row result is null, you can use the
     <code class="literal">IS NULL</code> conditional.  There is, however, no
     way to tell whether any additional rows might have been
     discarded.  Here is an example that handles the case where no
     rows have been returned:
</p>
<pre class="programlisting">DECLARE
    users_rec RECORD;
BEGIN
    SELECT INTO users_rec * FROM users WHERE user_id=3;

    IF users_rec.homepage IS NULL THEN
        -- user entered no homepage, return "http://"
        RETURN 'http://';
    END IF;
END;</pre>
<p>
    </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-statements-perform"></a>36.6.3.Executing an Expression or Query With No Result</h3></div></div></div>
<p>     Sometimes one wishes to evaluate an expression or query but
     discard the result (typically because one is calling a function
     that has useful side-effects but no useful result value).  To do
     this in <span class="application">PL/pgSQL</span>, use the
     <code class="command">PERFORM</code> statement:

</p>
<pre class="synopsis">PERFORM <em class="replaceable"><code>query</code></em>;</pre>
<p>

     This executes <em class="replaceable"><code>query</code></em> and discards the
     result.  Write the <em class="replaceable"><code>query</code></em> the same
     way as you would in an SQL <code class="command">SELECT</code> command, but replace the
     initial keyword <code class="command">SELECT</code> with <code class="command">PERFORM</code>.
     <span class="application">PL/pgSQL</span> variables will be
     substituted into the query as usual.  Also, the special variable
     <code class="literal">FOUND</code> is set to true if the query produced at
     least one row or false if it produced no rows.
    </p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>      One might expect that <code class="command">SELECT</code> with no
      <code class="literal">INTO</code> clause would accomplish this result, but at
      present the only accepted way to do it is
      <code class="command">PERFORM</code>.
     </p>
</div>
<p>     An example:
</p>
<pre class="programlisting">PERFORM create_mv('cs_session_page_requests_mv', my_query);</pre>
<p>
    </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-statements-null"></a>36.6.4.Doing Nothing At All</h3></div></div></div>
<p>     Sometimes a placeholder statement that does nothing is useful.
     For example, it can indicate that one arm of an if/then/else
     chain is deliberately empty.  For this purpose, use the
     <code class="command">NULL</code> statement:

</p>
<pre class="synopsis">NULL;</pre>
<p>
    </p>
<p>     For example, the following two fragments of code are equivalent:
</p>
<pre class="programlisting">    BEGIN
        y := x / 0;
    EXCEPTION
        WHEN division_by_zero THEN
            NULL;  -- ignore the error
    END;</pre>
<p>

</p>
<pre class="programlisting">    BEGIN
        y := x / 0;
    EXCEPTION
        WHEN division_by_zero THEN  -- ignore the error
    END;</pre>
<p>
     Which is preferable is a matter of taste.
    </p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>      In Oracle's PL/SQL, empty statement lists are not allowed, and so
      <code class="command">NULL</code> statements are <span class="emphasis"><em>required</em></span> for situations
      such as this.  <span class="application">PL/pgSQL</span> allows you to
      just write nothing, instead.
     </p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-statements-executing-dyn"></a>36.6.5.Executing Dynamic Commands</h3></div></div></div>
<p>     Oftentimes you will want to generate dynamic commands inside your
     <span class="application">PL/pgSQL</span> functions, that is, commands
     that will involve different tables or different data types each
     time they are executed.  <span class="application">PL/pgSQL</span>'s
     normal attempts to cache plans for commands will not work in such
     scenarios.  To handle this sort of problem, the
     <code class="command">EXECUTE</code> statement is provided:

</p>
<pre class="synopsis">EXECUTE <em class="replaceable"><code>command-string</code></em> [ INTO <em class="replaceable"><code>target</code></em> ];</pre>
<p>

     where <em class="replaceable"><code>command-string</code></em> is an expression
     yielding a string (of type <code class="type">text</code>) containing the
     command to be executed and <em class="replaceable"><code>target</code></em> is a
     record variable, row variable, or a comma-separated list of
     simple variables and record/row fields.
    </p>
<p>     Note in particular that no substitution of <span class="application">PL/pgSQL</span>
     variables is done on the command string.  The values of variables must
     be inserted in the command string as it is constructed.
    </p>
<p>     Unlike all other commands in <span class="application">PL/pgSQL</span>, a command
     run by an <code class="command">EXECUTE</code> statement is not prepared
     and saved just once during the life of the session.  Instead, the
     command is prepared each time the statement is run. The command
     string can be dynamically created within the function to perform
     actions on different tables and columns.
    </p>
<p>     The <code class="literal">INTO</code> clause specifies where the results of
     a <code class="command">SELECT</code> command should be assigned. If a row
     or variable list is provided, it must exactly match the structure
     of the results produced by the <code class="command">SELECT</code> (when a
     record variable is used, it will configure itself to match the
     result's structure automatically). If multiple rows are returned,
     only the first will be assigned to the <code class="literal">INTO</code>
     variable. If no rows are returned, NULL is assigned to the
     <code class="literal">INTO</code> variable. If no <code class="literal">INTO</code>
     clause is specified, the results of a <code class="command">SELECT</code>
     command are discarded.
    </p>
<p>     <code class="command">SELECT INTO</code> is not currently supported within
     <code class="command">EXECUTE</code>.
    </p>
<p>     When working with dynamic commands you will often have to handle escaping
     of single quotes.  The recommended method for quoting fixed text in your
     function body is dollar quoting.  (If you have legacy code that does
     not use dollar quoting, please refer to the
     overview in <a href="plpgsql-development-tips.html#plpgsql-quote-tips" title="36.2.1.Handling of Quotation Marks">Section36.2.1, &#8220;Handling of Quotation Marks&#8221;</a>, which can save you
     some effort when translating said code to a more reasonable scheme.)
    </p>
<p>     Dynamic values that are to be inserted into the constructed
     query require special handling since they might themselves contain
     quote characters.
     An example (this assumes that you are using dollar quoting for the
     function as a whole, so the quote marks need not be doubled):
</p>
<pre class="programlisting">EXECUTE 'UPDATE tbl SET '
        || quote_ident(colname)
        || ' = '
        || quote_literal(newvalue)
        || ' WHERE key = '
        || quote_literal(keyvalue);</pre>
<p>
    </p>
<a name="id723692"></a><a name="id723701"></a><p>     This example demonstrates the use of the
     <code class="function">quote_ident</code> and
     <code class="function">quote_literal</code> functions.  For safety,
     expressions containing column and table identifiers should be
     passed to <code class="function">quote_ident</code>.  Expressions containing
     values that should be literal strings in the constructed command
     should be passed to <code class="function">quote_literal</code>.  Both
     take the appropriate steps to return the input text enclosed in
     double or single quotes respectively, with any embedded special
     characters properly escaped.
    </p>
<p>     Note that dollar quoting is only useful for quoting fixed text.
     It would be a very bad idea to try to do the above example as
</p>
<pre class="programlisting">EXECUTE 'UPDATE tbl SET '
        || quote_ident(colname)
        || ' = $$'
        || newvalue
        || '$$ WHERE key = '
        || quote_literal(keyvalue);</pre>
<p>
     because it would break if the contents of <code class="literal">newvalue</code>
     happened to contain <code class="literal">$$</code>.  The same objection would
     apply to any other dollar-quoting delimiter you might pick.
     So, to safely quote text that is not known in advance, you
     <span class="emphasis"><em>must</em></span> use <code class="function">quote_literal</code>.
    </p>
<p>     A much larger example of a dynamic command and
     <code class="command">EXECUTE</code> can be seen in <a href="plpgsql-porting.html#plpgsql-porting-ex2" title="Example36.6.Porting a Function that Creates Another Function from PL/SQL to PL/pgSQL">Example36.6, &#8220;Porting a Function that Creates Another Function from <span class="application">PL/SQL</span> to <span class="application">PL/pgSQL</span>&#8221;</a>, which builds and executes a
     <code class="command">CREATE FUNCTION</code> command to define a new function.
    </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="plpgsql-statements-diagnostics"></a>36.6.6.Obtaining the Result Status</h3></div></div></div>
<p>     There are several ways to determine the effect of a command. The
     first method is to use the <code class="command">GET DIAGNOSTICS</code>
     command, which has the form:

</p>
<pre class="synopsis">GET DIAGNOSTICS <em class="replaceable"><code>variable</code></em> = <em class="replaceable"><code>item</code></em> [<span class="optional"> , ... </span>];</pre>
<p>

     This command allows retrieval of system status indicators.  Each
     <em class="replaceable"><code>item</code></em> is a key word identifying a state
     value to be assigned to the specified variable (which should be
     of the right data type to receive it).  The currently available
     status items are <code class="varname">ROW_COUNT</code>, the number of rows
     processed by the last <acronym class="acronym">SQL</acronym> command sent down to
     the <acronym class="acronym">SQL</acronym> engine, and <code class="varname">RESULT_OID</code>,
     the OID of the last row inserted by the most recent
     <acronym class="acronym">SQL</acronym> command.  Note that <code class="varname">RESULT_OID</code>
     is only useful after an <code class="command">INSERT</code> command into a
     table containing OIDs.
    </p>
<p>     An example:
</p>
<pre class="programlisting">GET DIAGNOSTICS integer_var = ROW_COUNT;</pre>
<p>
    </p>
<p>     The second method to determine the effects of a command is to check the
     special variable named <code class="literal">FOUND</code>, which is of
     type <code class="type">boolean</code>.  <code class="literal">FOUND</code> starts out
     false within each <span class="application">PL/pgSQL</span> function call.
     It is set by each of the following types of statements:
         </p>
<div class="itemizedlist"><ul type="disc">
<li><p>                A <code class="command">SELECT INTO</code> statement sets
                <code class="literal">FOUND</code> true if it returns a row, false if no
                row is returned.
           </p></li>
<li><p>                A <code class="command">PERFORM</code> statement sets <code class="literal">FOUND</code>
                true if it produces (and discards) a row, false if no row is
                produced.
           </p></li>
<li><p>                <code class="command">UPDATE</code>, <code class="command">INSERT</code>, and <code class="command">DELETE</code>
                statements set <code class="literal">FOUND</code> true if at least one
                row is affected, false if no row is affected.
           </p></li>
<li><p>                A <code class="command">FETCH</code> statement sets <code class="literal">FOUND</code>
                true if it returns a row, false if no row is returned.
           </p></li>
<li><p>                A <code class="command">FOR</code> statement sets <code class="literal">FOUND</code> true
                if it iterates one or more times, else false.  This applies to
                all three variants of the <code class="command">FOR</code> statement (integer
                <code class="command">FOR</code> loops, record-set <code class="command">FOR</code> loops, and
                dynamic record-set <code class="command">FOR</code>
                loops). <code class="literal">FOUND</code> is set this way when the
                <code class="command">FOR</code> loop exits; inside the execution of the loop,
                <code class="literal">FOUND</code> is not modified by the
                <code class="command">FOR</code> statement, although it may be changed by the
                execution of other statements within the loop body.
           </p></li>
</ul></div>
<p>

     <code class="literal">FOUND</code> is a local variable within each
     <span class="application">PL/pgSQL</span> function; any changes to it
     affect only the current function.
    </p>
</div>
</div></body>
</html>