Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3d4890c

Browse files
committed
Add GET STACKED DIAGNOSTICS plpgsql command to retrieve exception info.
This is more SQL-spec-compliant, more easily extensible, and betterperforming than the old method of inventing special variables.Pavel Stehule, reviewed by Shigeru Hanada and David Wheeler
1 parent3406dd2 commit3d4890c

File tree

9 files changed

+480
-66
lines changed

9 files changed

+480
-66
lines changed

‎doc/src/sgml/plpgsql.sgml

Lines changed: 106 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,11 +1387,11 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
13871387
command, which has the form:
13881388

13891389
<synopsis>
1390-
GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
1390+
GET<optional> CURRENT </optional>DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
13911391
</synopsis>
13921392

13931393
This command allows retrieval of system status indicators. Each
1394-
<replaceable>item</replaceable> is a key word identifying astate
1394+
<replaceable>item</replaceable> is a key word identifying astatus
13951395
value to be assigned to the specified variable (which should be
13961396
of the right data type to receive it). The currently available
13971397
status items are <varname>ROW_COUNT</>, the number of rows
@@ -2522,16 +2522,6 @@ END;
25222522
</para>
25232523
</tip>
25242524

2525-
<para>
2526-
Within an exception handler, the <varname>SQLSTATE</varname>
2527-
variable contains the error code that corresponds to the
2528-
exception that was raised (refer to <xref
2529-
linkend="errcodes-table"> for a list of possible error
2530-
codes). The <varname>SQLERRM</varname> variable contains the
2531-
error message associated with the exception. These variables are
2532-
undefined outside exception handlers.
2533-
</para>
2534-
25352525
<example id="plpgsql-upsert-example">
25362526
<title>Exceptions with <command>UPDATE</>/<command>INSERT</></title>
25372527
<para>
@@ -2568,11 +2558,112 @@ LANGUAGE plpgsql;
25682558
SELECT merge_db(1, 'david');
25692559
SELECT merge_db(1, 'dennis');
25702560
</programlisting>
2571-
This example assumes the <literal>unique_violation</> error is caused by
2572-
the <command>INSERT</>, and not by an <command>INSERT</> trigger function
2573-
on the table.
2561+
2562+
This coding assumes the <literal>unique_violation</> error is caused by
2563+
the <command>INSERT</>, and not by, say, an <command>INSERT</> in a
2564+
trigger function on the table. More safety could be had by using the
2565+
features discussed next to check that the trapped error was the one
2566+
expected.
25742567
</para>
25752568
</example>
2569+
2570+
<sect3 id="plpgsql-exception-diagnostics">
2571+
<title>Obtaining information about an error</title>
2572+
2573+
<para>
2574+
Exception handlers frequently need to identify the specific error that
2575+
occurred. There are two ways to get information about the current
2576+
exception in <application>PL/pgSQL</>: special variables and the
2577+
<command>GET STACKED DIAGNOSTICS</command> command.
2578+
</para>
2579+
2580+
<para>
2581+
Within an exception handler, the special variable
2582+
<varname>SQLSTATE</varname> contains the error code that corresponds to
2583+
the exception that was raised (refer to <xref linkend="errcodes-table">
2584+
for a list of possible error codes). The special variable
2585+
<varname>SQLERRM</varname> contains the error message associated with the
2586+
exception. These variables are undefined outside exception handlers.
2587+
</para>
2588+
2589+
<para>
2590+
Within an exception handler, one may also retrieve
2591+
information about the current exception by using the
2592+
<command>GET STACKED DIAGNOSTICS</command> command, which has the form:
2593+
2594+
<synopsis>
2595+
GET STACKED DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
2596+
</synopsis>
2597+
2598+
Each <replaceable>item</replaceable> is a key word identifying a status
2599+
value to be assigned to the specified variable (which should be
2600+
of the right data type to receive it). The currently available
2601+
status items are:
2602+
2603+
<table id="plpgsql-exception-diagnostics-values">
2604+
<title>Error diagnostics values</title>
2605+
<tgroup cols="3">
2606+
<thead>
2607+
<row>
2608+
<entry>Name</entry>
2609+
<entry>Type</entry>
2610+
<entry>Description</entry>
2611+
</row>
2612+
</thead>
2613+
<tbody>
2614+
<row>
2615+
<entry><literal>RETURNED_SQLSTATE</literal></entry>
2616+
<entry>text</entry>
2617+
<entry>the SQLSTATE error code of the exception</entry>
2618+
</row>
2619+
<row>
2620+
<entry><literal>MESSAGE_TEXT</literal></entry>
2621+
<entry>text</entry>
2622+
<entry>the text of the exception's primary message</entry>
2623+
</row>
2624+
<row>
2625+
<entry><literal>PG_EXCEPTION_DETAIL</literal></entry>
2626+
<entry>text</entry>
2627+
<entry>the text of the exception's detail message, if any</entry>
2628+
</row>
2629+
<row>
2630+
<entry><literal>PG_EXCEPTION_HINT</literal></entry>
2631+
<entry>text</entry>
2632+
<entry>the text of the exception's hint message, if any</entry>
2633+
</row>
2634+
<row>
2635+
<entry><literal>PG_EXCEPTION_CONTEXT</literal></entry>
2636+
<entry>text</entry>
2637+
<entry>line(s) of text describing the call stack</entry>
2638+
</row>
2639+
</tbody>
2640+
</tgroup>
2641+
</table>
2642+
</para>
2643+
2644+
<para>
2645+
If the exception did not set a value for an item, an empty string
2646+
will be returned.
2647+
</para>
2648+
2649+
<para>
2650+
Here is an example:
2651+
<programlisting>
2652+
DECLARE
2653+
text_var1 text;
2654+
text_var2 text;
2655+
text_var3 text;
2656+
BEGIN
2657+
-- some processing which might cause an exception
2658+
...
2659+
EXCEPTION WHEN OTHERS THEN
2660+
GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
2661+
text_var2 = PG_EXCEPTION_DETAIL,
2662+
text_var3 = PG_EXCEPTION_HINT;
2663+
END;
2664+
</programlisting>
2665+
</para>
2666+
</sect3>
25762667
</sect2>
25772668
</sect1>
25782669

‎src/backend/utils/errcodes.txt

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@
5151
# class (the first two characters of the code value identify the class).
5252
# The listing is organized by class to make this prominent.
5353
#
54-
# The generic '000' subclass code should be used for an error only
54+
# Each class should have a generic '000' subclass. However,
55+
# the generic '000' subclass code should be used for an error only
5556
# when there is not a more-specific subclass code defined.
5657
#
5758
# The SQL spec requires that all the elements of a SQLSTATE code be
@@ -132,6 +133,11 @@ Section: Class 0P - Invalid Role Specification
132133

133134
0P000 E ERRCODE_INVALID_ROLE_SPECIFICATION invalid_role_specification
134135

136+
Section: Class 0Z - Diagnostics Exception
137+
138+
0Z000 E ERRCODE_DIAGNOSTICS_EXCEPTION diagnostics_exception
139+
0Z002 E ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER stacked_diagnostics_accessed_without_active_handler
140+
135141
Section: Class 20 - Case Not Found
136142

137143
20000 E ERRCODE_CASE_NOT_FOUND case_not_found
@@ -399,6 +405,7 @@ Section: Class 57 - Operator Intervention
399405
Section: Class 58 - System Error (errors external to PostgreSQL itself)
400406

401407
# (class borrowed from DB2)
408+
58000 E ERRCODE_SYSTEM_ERROR system_error
402409
58030 E ERRCODE_IO_ERROR io_error
403410
58P01 E ERRCODE_UNDEFINED_FILE undefined_file
404411
58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
@@ -415,30 +422,30 @@ Section: Class HV - Foreign Data Wrapper Error (SQL/MED)
415422
HV000 E ERRCODE_FDW_ERROR fdw_error
416423
HV005 E ERRCODE_FDW_COLUMN_NAME_NOT_FOUND fdw_column_name_not_found
417424
HV002 E ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED fdw_dynamic_parameter_value_needed
418-
HV010 E ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR fdw_function_sequence_error
425+
HV010 E ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR fdw_function_sequence_error
419426
HV021 E ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION fdw_inconsistent_descriptor_information
420-
HV024 E ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE fdw_invalid_attribute_value
421-
HV007 E ERRCODE_FDW_INVALID_COLUMN_NAME fdw_invalid_column_name
422-
HV008 E ERRCODE_FDW_INVALID_COLUMN_NUMBER fdw_invalid_column_number
423-
HV004 E ERRCODE_FDW_INVALID_DATA_TYPE fdw_invalid_data_type
424-
HV006 E ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS fdw_invalid_data_type_descriptors
425-
HV091 E ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER fdw_invalid_descriptor_field_identifier
426-
HV00B E ERRCODE_FDW_INVALID_HANDLE fdw_invalid_handle
427-
HV00C E ERRCODE_FDW_INVALID_OPTION_INDEX fdw_invalid_option_index
428-
HV00D E ERRCODE_FDW_INVALID_OPTION_NAME fdw_invalid_option_name
429-
HV090 E ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH fdw_invalid_string_length_or_buffer_length
430-
HV00A E ERRCODE_FDW_INVALID_STRING_FORMAT fdw_invalid_string_format
431-
HV009 E ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER fdw_invalid_use_of_null_pointer
432-
HV014 E ERRCODE_FDW_TOO_MANY_HANDLES fdw_too_many_handles
433-
HV001 E ERRCODE_FDW_OUT_OF_MEMORY fdw_out_of_memory
434-
HV00P E ERRCODE_FDW_NO_SCHEMAS fdw_no_schemas
435-
HV00J E ERRCODE_FDW_OPTION_NAME_NOT_FOUND fdw_option_name_not_found
436-
HV00K E ERRCODE_FDW_REPLY_HANDLE fdw_reply_handle
437-
HV00Q E ERRCODE_FDW_SCHEMA_NOT_FOUND fdw_schema_not_found
438-
HV00R E ERRCODE_FDW_TABLE_NOT_FOUND fdw_table_not_found
439-
HV00L E ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION fdw_unable_to_create_execution
440-
HV00M E ERRCODE_FDW_UNABLE_TO_CREATE_REPLY fdw_unable_to_create_reply
441-
HV00N E ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION fdw_unable_to_establish_connection
427+
HV024 E ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE fdw_invalid_attribute_value
428+
HV007 E ERRCODE_FDW_INVALID_COLUMN_NAME fdw_invalid_column_name
429+
HV008 E ERRCODE_FDW_INVALID_COLUMN_NUMBER fdw_invalid_column_number
430+
HV004 E ERRCODE_FDW_INVALID_DATA_TYPE fdw_invalid_data_type
431+
HV006 E ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS fdw_invalid_data_type_descriptors
432+
HV091 E ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER fdw_invalid_descriptor_field_identifier
433+
HV00B E ERRCODE_FDW_INVALID_HANDLE fdw_invalid_handle
434+
HV00C E ERRCODE_FDW_INVALID_OPTION_INDEX fdw_invalid_option_index
435+
HV00D E ERRCODE_FDW_INVALID_OPTION_NAME fdw_invalid_option_name
436+
HV090 E ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH fdw_invalid_string_length_or_buffer_length
437+
HV00A E ERRCODE_FDW_INVALID_STRING_FORMAT fdw_invalid_string_format
438+
HV009 E ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER fdw_invalid_use_of_null_pointer
439+
HV014 E ERRCODE_FDW_TOO_MANY_HANDLES fdw_too_many_handles
440+
HV001 E ERRCODE_FDW_OUT_OF_MEMORY fdw_out_of_memory
441+
HV00P E ERRCODE_FDW_NO_SCHEMAS fdw_no_schemas
442+
HV00J E ERRCODE_FDW_OPTION_NAME_NOT_FOUND fdw_option_name_not_found
443+
HV00K E ERRCODE_FDW_REPLY_HANDLE fdw_reply_handle
444+
HV00Q E ERRCODE_FDW_SCHEMA_NOT_FOUND fdw_schema_not_found
445+
HV00R E ERRCODE_FDW_TABLE_NOT_FOUND fdw_table_not_found
446+
HV00L E ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION fdw_unable_to_create_execution
447+
HV00M E ERRCODE_FDW_UNABLE_TO_CREATE_REPLY fdw_unable_to_create_reply
448+
HV00N E ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION fdw_unable_to_establish_connection
442449

443450
Section: Class P0 - PL/pgSQL Error
444451

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp