diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-05-13 22:10:30 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-05-13 22:10:30 +0000 |
| commit | 4107478d374fae8299b6eb17fd13e65b7d8e026a (patch) | |
| tree | 8b5c88f19f9a3a59ad034a9e8ececa072101efba /doc/src | |
| parent | 72e2db86b9845f75ebf538dd96614b1dab6cfb04 (diff) | |
Improve plpgsql's RAISE command. It is now possible to attach DETAIL and
HINT fields to a user-thrown error message, and to specify the SQLSTATE
error code to use. The syntax has also been tweaked so that the
Oracle-compatible case "RAISE exception_name" works (though you won't get a
very nice error message if you just write that much). Lastly, support
the Oracle-compatible syntax "RAISE" with no parameters to re-throw
the current error from within an EXCEPTION block.
In passing, allow the syntax SQLSTATE 'nnnnn' within EXCEPTION lists,
so that there is a way to trap errors with custom SQLSTATE codes.
Pavel Stehule and Tom Lane
Diffstat (limited to 'doc/src')
| -rw-r--r-- | doc/src/sgml/plpgsql.sgml | 126 |
1 files changed, 104 insertions, 22 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 1065eddc74e..09ad6944dba 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.128 2008/05/03 00:11:36 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.129 2008/05/13 22:10:29 tgl Exp $ --> <chapter id="plpgsql"> <title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title> @@ -2133,7 +2133,12 @@ END; condition name <literal>OTHERS</> matches every error type except <literal>QUERY_CANCELED</>. (It is possible, but often unwise, to trap <literal>QUERY_CANCELED</> by name.) Condition names are - not case-sensitive. + not case-sensitive. Also, an error condition can be specified + by <literal>SQLSTATE</> code; for example these are equivalent: +<programlisting> + WHEN division_by_zero THEN ... + WHEN SQLSTATE '22012' THEN ... +</programlisting> </para> <para> @@ -2750,13 +2755,19 @@ END LOOP <optional> <replaceable>label</replaceable> </optional>; raise errors. <synopsis> -RAISE <replaceable class="parameter">level</replaceable> '<replaceable class="parameter">format</replaceable>' <optional>, <replaceable class="parameter">expression</replaceable> <optional>, ...</optional></optional>; +RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> '<replaceable class="parameter">format</replaceable>' <optional>, <replaceable class="parameter">expression</replaceable> <optional>, ...</optional></optional> <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>; +RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> <replaceable class="parameter">condition_name</> <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>; +RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> SQLSTATE '<replaceable class="parameter">sqlstate</>' <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>; +RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional>; +RAISE ; </synopsis> - Possible levels are <literal>DEBUG</literal>, + The <replaceable class="parameter">level</replaceable> option specifies + the error severity. Allowed levels are <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>, - and <literal>EXCEPTION</literal>. + and <literal>EXCEPTION</literal>, with <literal>EXCEPTION</literal> + being the default. <literal>EXCEPTION</literal> raises an error (which normally aborts the current transaction); the other levels only generate messages of different priority levels. @@ -2769,19 +2780,17 @@ RAISE <replaceable class="parameter">level</replaceable> '<replaceable class="pa </para> <para> + After <replaceable class="parameter">level</replaceable> if any, + you can write a <replaceable class="parameter">format</replaceable> + (which must be a simple string literal, not an expression). The + format string specifies the error message text to be reported. + The format string can be followed + by optional argument expressions to be inserted into the message. Inside the format string, <literal>%</literal> is replaced by the - next optional argument's string representation. Write + string representation of the next optional argument's value. Write <literal>%%</literal> to emit a literal <literal>%</literal>. - Arguments can be simple variables or expressions, - but the format must be a simple string literal. </para> - <!-- - This example should work, but does not: - RAISE NOTICE 'Id number ' || key || ' not found!'; - Put it back when we allow non-string-literal formats. - --> - <para> In this example, the value of <literal>v_job_id</> will replace the <literal>%</literal> in the string: @@ -2791,19 +2800,90 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; </para> <para> - This example will abort the transaction with the given error message: + You can attach additional information to the error report by writing + <literal>USING</> followed by <replaceable + class="parameter">option</replaceable> = <replaceable + class="parameter">expression</replaceable> items. The allowed + <replaceable class="parameter">option</replaceable> keywords are + <literal>MESSAGE</>, <literal>DETAIL</>, <literal>HINT</>, and + <literal>ERRCODE</>, while each <replaceable + class="parameter">expression</replaceable> can be any string-valued + expression. + <literal>MESSAGE</> sets the error message text (this option can't + be used in the form of <command>RAISE</> that includes a format + string before <literal>USING</>). + <literal>DETAIL</> supplies an error detail message, while + <literal>HINT</> supplies a hint message. + <literal>ERRCODE</> specifies the error code (SQLSTATE) to report, + either by condition name as shown in <xref linkend="errcodes-appendix">, + or directly as a five-character SQLSTATE code. + </para> + + <para> + This example will abort the transaction with the given error message + and hint: +<programlisting> +RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user id'; +</programlisting> + </para> + + <para> + These two examples show equivalent ways of setting the SQLSTATE: +<programlisting> +RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; +RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; +</programlisting> + </para> + + <para> + There is a second <command>RAISE</> syntax in which the main argument + is the condition name or SQLSTATE to be reported, for example: +<programlisting> +RAISE division_by_zero; +RAISE SQLSTATE '22012'; +</programlisting> + In this syntax, <literal>USING</> can be used to supply a custom + error message, detail, or hint. Another way to do the earlier + example is <programlisting> -RAISE EXCEPTION 'Nonexistent ID --> %', user_id; +RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; </programlisting> </para> + <para> + Still another variant is to write <literal>RAISE USING</> or <literal>RAISE + <replaceable class="parameter">level</replaceable> USING</> and put + everything else into the <literal>USING</> list. + </para> + + <para> + The last variant of <command>RAISE</> has no parameters at all. + This form can only be used inside a <literal>BEGIN</> block's + <literal>EXCEPTION</> clause; + it causes the error currently being handled to be re-thrown to the + next enclosing block. + </para> + + <para> + If no condition name nor SQLSTATE is specified in a + <command>RAISE EXCEPTION</command> command, the default is to use + <literal>RAISE_EXCEPTION</> (<literal>P0001</>). If no message + text is specified, the default is to use the condition name or + SQLSTATE as message text. + </para> + + <note> <para> - <command>RAISE EXCEPTION</command> presently always generates - the same <varname>SQLSTATE</varname> code, <literal>P0001</>, no matter what message - it is invoked with. It is possible to trap this exception with - <literal>EXCEPTION ... WHEN RAISE_EXCEPTION THEN ...</> but there - is no way to tell one <command>RAISE</> from another. + When specifying an error code by SQLSTATE code, you are not + limited to the predefined error codes, but can select any + error code consisting of five digits and/or upper-case ASCII + letters, other than <literal>00000</>. It is recommended that + you avoid throwing error codes that end in three zeroes, because + these are category codes and can only be trapped by trapping + the whole category. </para> + </note> + </sect1> <sect1 id="plpgsql-trigger"> @@ -4307,7 +4387,9 @@ $$ LANGUAGE plpgsql; <callout arearefs="co.plpgsql-porting-raise"> <para> The syntax of <literal>RAISE</> is considerably different from - Oracle's similar statement. + Oracle's statement, although the basic case <literal>RAISE</> + <replaceable class="parameter">exception_name</replaceable> works + similarly. </para> </callout> <callout arearefs="co.plpgsql-porting-exception"> |
