2 41.5. Basic Statements #
5 41.5.2. Executing SQL Commands
6 41.5.3. Executing a Command with a Single-Row Result
7 41.5.4. Executing Dynamic Commands
8 41.5.5. Obtaining the Result Status
9 41.5.6. Doing Nothing At All
11 In this section and the following ones, we describe all the statement
12 types that are explicitly understood by PL/pgSQL. Anything not
13 recognized as one of these statement types is presumed to be an SQL
14 command and is sent to the main database engine to execute, as
15 described in Section 41.5.2.
19 An assignment of a value to a PL/pgSQL variable is written as:
20 variable { := | = } expression;
22 As explained previously, the expression in such a statement is
23 evaluated by means of an SQL SELECT command sent to the main database
24 engine. The expression must yield a single value (possibly a row value,
25 if the variable is a row or record variable). The target variable can
26 be a simple variable (optionally qualified with a block name), a field
27 of a row or record target, or an element or slice of an array target.
28 Equal (=) can be used instead of PL/SQL-compliant :=.
30 If the expression's result data type doesn't match the variable's data
31 type, the value will be coerced as though by an assignment cast (see
32 Section 10.4). If no assignment cast is known for the pair of data
33 types involved, the PL/pgSQL interpreter will attempt to convert the
34 result value textually, that is by applying the result type's output
35 function followed by the variable type's input function. Note that this
36 could result in run-time errors generated by the input function, if the
37 string form of the result value is not acceptable to the input
41 tax := subtotal * 0.06;
42 my_record.user_id := 20;
44 my_array[1:3] := array[1,2,3];
45 complex_array[n].realpart = 12.3;
47 41.5.2. Executing SQL Commands #
49 In general, any SQL command that does not return rows can be executed
50 within a PL/pgSQL function just by writing the command. For example,
51 you could create and fill a table by writing
52 CREATE TABLE mytable (id int primary key, data text);
53 INSERT INTO mytable VALUES (1,'one'), (2,'two');
55 If the command does return rows (for example SELECT, or
56 INSERT/UPDATE/DELETE/MERGE with RETURNING), there are two ways to
57 proceed. When the command will return at most one row, or you only care
58 about the first row of output, write the command as usual but add an
59 INTO clause to capture the output, as described in Section 41.5.3. To
60 process all of the output rows, write the command as the data source
61 for a FOR loop, as described in Section 41.6.6.
63 Usually it is not sufficient just to execute statically-defined SQL
64 commands. Typically you'll want a command to use varying data values,
65 or even to vary in more fundamental ways such as by using different
66 table names at different times. Again, there are two ways to proceed
67 depending on the situation.
69 PL/pgSQL variable values can be automatically inserted into optimizable
70 SQL commands, which are SELECT, INSERT, UPDATE, DELETE, MERGE, and
71 certain utility commands that incorporate one of these, such as EXPLAIN
72 and CREATE TABLE ... AS SELECT. In these commands, any PL/pgSQL
73 variable name appearing in the command text is replaced by a query
74 parameter, and then the current value of the variable is provided as
75 the parameter value at run time. This is exactly like the processing
76 described earlier for expressions; for details see Section 41.11.1.
78 When executing an optimizable SQL command in this way, PL/pgSQL may
79 cache and re-use the execution plan for the command, as discussed in
82 Non-optimizable SQL commands (also called utility commands) are not
83 capable of accepting query parameters. So automatic substitution of
84 PL/pgSQL variables does not work in such commands. To include
85 non-constant text in a utility command executed from PL/pgSQL, you must
86 build the utility command as a string and then EXECUTE it, as discussed
89 EXECUTE must also be used if you want to modify the command in some
90 other way than supplying a data value, for example by changing a table
93 Sometimes it is useful to evaluate an expression or SELECT query but
94 discard the result, for example when calling a function that has
95 side-effects but no useful result value. To do this in PL/pgSQL, use
96 the PERFORM statement:
99 This executes query and discards the result. Write the query the same
100 way you would write an SQL SELECT command, but replace the initial
101 keyword SELECT with PERFORM. For WITH queries, use PERFORM and then
102 place the query in parentheses. (In this case, the query can only
103 return one row.) PL/pgSQL variables will be substituted into the query
104 just as described above, and the plan is cached in the same way. Also,
105 the special variable FOUND is set to true if the query produced at
106 least one row, or false if it produced no rows (see Section 41.5.5).
110 One might expect that writing SELECT directly would accomplish this
111 result, but at present the only accepted way to do it is PERFORM. An
112 SQL command that can return rows, such as SELECT, will be rejected as
113 an error unless it has an INTO clause as discussed in the next section.
116 PERFORM create_mv('cs_session_page_requests_mv', my_query);
118 41.5.3. Executing a Command with a Single-Row Result #
120 The result of an SQL command yielding a single row (possibly of
121 multiple columns) can be assigned to a record variable, row-type
122 variable, or list of scalar variables. This is done by writing the base
123 SQL command and adding an INTO clause. For example,
124 SELECT select_expressions INTO [STRICT] target FROM ...;
125 INSERT ... RETURNING expressions INTO [STRICT] target;
126 UPDATE ... RETURNING expressions INTO [STRICT] target;
127 DELETE ... RETURNING expressions INTO [STRICT] target;
128 MERGE ... RETURNING expressions INTO [STRICT] target;
130 where target can be a record variable, a row variable, or a
131 comma-separated list of simple variables and record/row fields.
132 PL/pgSQL variables will be substituted into the rest of the command
133 (that is, everything but the INTO clause) just as described above, and
134 the plan is cached in the same way. This works for SELECT,
135 INSERT/UPDATE/DELETE/MERGE with RETURNING, and certain utility commands
136 that return row sets, such as EXPLAIN. Except for the INTO clause, the
137 SQL command is the same as it would be written outside PL/pgSQL.
141 Note that this interpretation of SELECT with INTO is quite different
142 from PostgreSQL's regular SELECT INTO command, wherein the INTO target
143 is a newly created table. If you want to create a table from a SELECT
144 result inside a PL/pgSQL function, use the syntax CREATE TABLE ... AS
147 If a row variable or a variable list is used as target, the command's
148 result columns must exactly match the structure of the target as to
149 number and data types, or else a run-time error occurs. When a record
150 variable is the target, it automatically configures itself to the row
151 type of the command's result columns.
153 The INTO clause can appear almost anywhere in the SQL command.
154 Customarily it is written either just before or just after the list of
155 select_expressions in a SELECT command, or at the end of the command
156 for other command types. It is recommended that you follow this
157 convention in case the PL/pgSQL parser becomes stricter in future
160 If STRICT is not specified in the INTO clause, then target will be set
161 to the first row returned by the command, or to nulls if the command
162 returned no rows. (Note that “the first row” is not well-defined unless
163 you've used ORDER BY.) Any result rows after the first row are
164 discarded. You can check the special FOUND variable (see
165 Section 41.5.5) to determine whether a row was returned:
166 SELECT * INTO myrec FROM emp WHERE empname = myname;
168 RAISE EXCEPTION 'employee % not found', myname;
171 If the STRICT option is specified, the command must return exactly one
172 row or a run-time error will be reported, either NO_DATA_FOUND (no
173 rows) or TOO_MANY_ROWS (more than one row). You can use an exception
174 block if you wish to catch the error, for example:
176 SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
178 WHEN NO_DATA_FOUND THEN
179 RAISE EXCEPTION 'employee % not found', myname;
180 WHEN TOO_MANY_ROWS THEN
181 RAISE EXCEPTION 'employee % not unique', myname;
184 Successful execution of a command with STRICT always sets FOUND to
187 For INSERT/UPDATE/DELETE/MERGE with RETURNING, PL/pgSQL reports an
188 error for more than one returned row, even when STRICT is not
189 specified. This is because there is no option such as ORDER BY with
190 which to determine which affected row should be returned.
192 If print_strict_params is enabled for the function, then when an error
193 is thrown because the requirements of STRICT are not met, the DETAIL
194 part of the error message will include information about the parameters
195 passed to the command. You can change the print_strict_params setting
196 for all functions by setting plpgsql.print_strict_params, though only
197 subsequent function compilations will be affected. You can also enable
198 it on a per-function basis by using a compiler option, for example:
199 CREATE FUNCTION get_userid(username text) RETURNS int
201 #print_strict_params on
205 SELECT users.userid INTO STRICT userid
206 FROM users WHERE users.username = get_userid.username;
211 On failure, this function might produce an error message such as
212 ERROR: query returned no rows
213 DETAIL: parameters: username = 'nosuchuser'
214 CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
218 The STRICT option matches the behavior of Oracle PL/SQL's SELECT INTO
219 and related statements.
221 41.5.4. Executing Dynamic Commands #
223 Oftentimes you will want to generate dynamic commands inside your
224 PL/pgSQL functions, that is, commands that will involve different
225 tables or different data types each time they are executed. PL/pgSQL's
226 normal attempts to cache plans for commands (as discussed in
227 Section 41.11.2) will not work in such scenarios. To handle this sort
228 of problem, the EXECUTE statement is provided:
229 EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
231 where command-string is an expression yielding a string (of type text)
232 containing the command to be executed. The optional target is a record
233 variable, a row variable, or a comma-separated list of simple variables
234 and record/row fields, into which the results of the command will be
235 stored. The optional USING expressions supply values to be inserted
238 No substitution of PL/pgSQL variables is done on the computed command
239 string. Any required variable values must be inserted in the command
240 string as it is constructed; or you can use parameters as described
243 Also, there is no plan caching for commands executed via EXECUTE.
244 Instead, the command is always planned each time the statement is run.
245 Thus the command string can be dynamically created within the function
246 to perform actions on different tables and columns.
248 The INTO clause specifies where the results of an SQL command returning
249 rows should be assigned. If a row variable or variable list is
250 provided, it must exactly match the structure of the command's results;
251 if a record variable is provided, it will configure itself to match the
252 result structure automatically. If multiple rows are returned, only the
253 first will be assigned to the INTO variable(s). If no rows are
254 returned, NULL is assigned to the INTO variable(s). If no INTO clause
255 is specified, the command results are discarded.
257 If the STRICT option is given, an error is reported unless the command
258 produces exactly one row.
260 The command string can use parameter values, which are referenced in
261 the command as $1, $2, etc. These symbols refer to values supplied in
262 the USING clause. This method is often preferable to inserting data
263 values into the command string as text: it avoids run-time overhead of
264 converting the values to text and back, and it is much less prone to
265 SQL-injection attacks since there is no need for quoting or escaping.
267 EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
269 USING checked_user, checked_date;
271 Note that parameter symbols can only be used for data values — if you
272 want to use dynamically determined table or column names, you must
273 insert them into the command string textually. For example, if the
274 preceding query needed to be done against a dynamically selected table,
276 EXECUTE 'SELECT count(*) FROM '
277 || quote_ident(tabname)
278 || ' WHERE inserted_by = $1 AND inserted <= $2'
280 USING checked_user, checked_date;
282 A cleaner approach is to use format()'s %I specification to insert
283 table or column names with automatic quoting:
284 EXECUTE format('SELECT count(*) FROM %I '
285 'WHERE inserted_by = $1 AND inserted <= $2', tabname)
287 USING checked_user, checked_date;
289 (This example relies on the SQL rule that string literals separated by
290 a newline are implicitly concatenated.)
292 Another restriction on parameter symbols is that they only work in
293 optimizable SQL commands (SELECT, INSERT, UPDATE, DELETE, MERGE, and
294 certain commands containing one of these). In other statement types
295 (generically called utility statements), you must insert values
296 textually even if they are just data values.
298 An EXECUTE with a simple constant command string and some USING
299 parameters, as in the first example above, is functionally equivalent
300 to just writing the command directly in PL/pgSQL and allowing
301 replacement of PL/pgSQL variables to happen automatically. The
302 important difference is that EXECUTE will re-plan the command on each
303 execution, generating a plan that is specific to the current parameter
304 values; whereas PL/pgSQL may otherwise create a generic plan and cache
305 it for re-use. In situations where the best plan depends strongly on
306 the parameter values, it can be helpful to use EXECUTE to positively
307 ensure that a generic plan is not selected.
309 SELECT INTO is not currently supported within EXECUTE; instead, execute
310 a plain SELECT command and specify INTO as part of the EXECUTE itself.
314 The PL/pgSQL EXECUTE statement is not related to the EXECUTE SQL
315 statement supported by the PostgreSQL server. The server's EXECUTE
316 statement cannot be used directly within PL/pgSQL functions (and is not
319 Example 41.1. Quoting Values in Dynamic Queries
321 When working with dynamic commands you will often have to handle
322 escaping of single quotes. The recommended method for quoting fixed
323 text in your function body is dollar quoting. (If you have legacy code
324 that does not use dollar quoting, please refer to the overview in
325 Section 41.12.1, which can save you some effort when translating said
326 code to a more reasonable scheme.)
328 Dynamic values require careful handling since they might contain quote
329 characters. An example using format() (this assumes that you are dollar
330 quoting the function body so quote marks need not be doubled):
331 EXECUTE format('UPDATE tbl SET %I = $1 '
332 'WHERE key = $2', colname) USING newvalue, keyvalue;
334 It is also possible to call the quoting functions directly:
335 EXECUTE 'UPDATE tbl SET '
336 || quote_ident(colname)
338 || quote_literal(newvalue)
340 || quote_literal(keyvalue);
342 This example demonstrates the use of the quote_ident and quote_literal
343 functions (see Section 9.4). For safety, expressions containing column
344 or table identifiers should be passed through quote_ident before
345 insertion in a dynamic query. Expressions containing values that should
346 be literal strings in the constructed command should be passed through
347 quote_literal. These functions take the appropriate steps to return the
348 input text enclosed in double or single quotes respectively, with any
349 embedded special characters properly escaped.
351 Because quote_literal is labeled STRICT, it will always return null
352 when called with a null argument. In the above example, if newvalue or
353 keyvalue were null, the entire dynamic query string would become null,
354 leading to an error from EXECUTE. You can avoid this problem by using
355 the quote_nullable function, which works the same as quote_literal
356 except that when called with a null argument it returns the string
358 EXECUTE 'UPDATE tbl SET '
359 || quote_ident(colname)
361 || quote_nullable(newvalue)
363 || quote_nullable(keyvalue);
365 If you are dealing with values that might be null, you should usually
366 use quote_nullable in place of quote_literal.
368 As always, care must be taken to ensure that null values in a query do
369 not deliver unintended results. For example the WHERE clause
370 'WHERE key = ' || quote_nullable(keyvalue)
372 will never succeed if keyvalue is null, because the result of using the
373 equality operator = with a null operand is always null. If you wish
374 null to work like an ordinary key value, you would need to rewrite the
376 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue)
378 (At present, IS NOT DISTINCT FROM is handled much less efficiently than
379 =, so don't do this unless you must. See Section 9.2 for more
380 information on nulls and IS DISTINCT.)
382 Note that dollar quoting is only useful for quoting fixed text. It
383 would be a very bad idea to try to write this example as:
384 EXECUTE 'UPDATE tbl SET '
385 || quote_ident(colname)
389 || quote_literal(keyvalue);
391 because it would break if the contents of newvalue happened to contain
392 $$. The same objection would apply to any other dollar-quoting
393 delimiter you might pick. So, to safely quote text that is not known in
394 advance, you must use quote_literal, quote_nullable, or quote_ident, as
397 Dynamic SQL statements can also be safely constructed using the format
398 function (see Section 9.4.1). For example:
399 EXECUTE format('UPDATE tbl SET %I = %L '
400 'WHERE key = %L', colname, newvalue, keyvalue);
402 %I is equivalent to quote_ident, and %L is equivalent to
403 quote_nullable. The format function can be used in conjunction with the
405 EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
406 USING newvalue, keyvalue;
408 This form is better because the variables are handled in their native
409 data type format, rather than unconditionally converting them to text
410 and quoting them via %L. It is also more efficient.
412 A much larger example of a dynamic command and EXECUTE can be seen in
413 Example 41.10, which builds and executes a CREATE FUNCTION command to
414 define a new function.
416 41.5.5. Obtaining the Result Status #
418 There are several ways to determine the effect of a command. The first
419 method is to use the GET DIAGNOSTICS command, which has the form:
420 GET [ CURRENT ] DIAGNOSTICS variable { = | := } item [ , ... ];
422 This command allows retrieval of system status indicators. CURRENT is a
423 noise word (but see also GET STACKED DIAGNOSTICS in Section 41.6.8.1).
424 Each item is a key word identifying a status value to be assigned to
425 the specified variable (which should be of the right data type to
426 receive it). The currently available status items are shown in
427 Table 41.1. Colon-equal (:=) can be used instead of the SQL-standard =
429 GET DIAGNOSTICS integer_var = ROW_COUNT;
431 Table 41.1. Available Diagnostics Items
432 Name Type Description
433 ROW_COUNT bigint the number of rows processed by the most recent SQL
435 PG_CONTEXT text line(s) of text describing the current call stack (see
437 PG_ROUTINE_OID oid OID of the current function
439 The second method to determine the effects of a command is to check the
440 special variable named FOUND, which is of type boolean. FOUND starts
441 out false within each PL/pgSQL function call. It is set by each of the
442 following types of statements:
443 * A SELECT INTO statement sets FOUND true if a row is assigned, false
444 if no row is returned.
445 * A PERFORM statement sets FOUND true if it produces (and discards)
446 one or more rows, false if no row is produced.
447 * UPDATE, INSERT, DELETE, and MERGE statements set FOUND true if at
448 least one row is affected, false if no row is affected.
449 * A FETCH statement sets FOUND true if it returns a row, false if no
451 * A MOVE statement sets FOUND true if it successfully repositions the
452 cursor, false otherwise.
453 * A FOR or FOREACH statement sets FOUND true if it iterates one or
454 more times, else false. FOUND is set this way when the loop exits;
455 inside the execution of the loop, FOUND is not modified by the loop
456 statement, although it might be changed by the execution of other
457 statements within the loop body.
458 * RETURN QUERY and RETURN QUERY EXECUTE statements set FOUND true if
459 the query returns at least one row, false if no row is returned.
461 Other PL/pgSQL statements do not change the state of FOUND. Note in
462 particular that EXECUTE changes the output of GET DIAGNOSTICS, but does
465 FOUND is a local variable within each PL/pgSQL function; any changes to
466 it affect only the current function.
468 41.5.6. Doing Nothing At All #
470 Sometimes a placeholder statement that does nothing is useful. For
471 example, it can indicate that one arm of an if/then/else chain is
472 deliberately empty. For this purpose, use the NULL statement:
475 For example, the following two fragments of code are equivalent:
479 WHEN division_by_zero THEN
480 NULL; -- ignore the error
486 WHEN division_by_zero THEN -- ignore the error
489 Which is preferable is a matter of taste.
493 In Oracle's PL/SQL, empty statement lists are not allowed, and so NULL
494 statements are required for situations such as this. PL/pgSQL allows
495 you to just write nothing, instead.