All Products
Search
Document Center

PolarDB:Error handling

Last Updated:Mar 28, 2026

PolarDB for PostgreSQL (Compatible with Oracle) supports both the native PostgreSQL error handling system and common Oracle PL/SQL error handling patterns, so you can use either style in your PL/SQL blocks.

Four mechanisms are supported:

  • Predefined exceptions: both PostgreSQL-style (e.g., division_by_zero) and Oracle-style (e.g., zero_divide)

  • Non-predefined exceptions: declare and bind unnamed Oracle error codes using PRAGMA EXCEPTION_INIT

  • User-defined exceptions: raise custom error codes and messages using RAISE_APPLICATION_ERROR

  • Error codes and messages: SQLSTATE (PostgreSQL), SQLCODE (Oracle-compatible), and SQLERRM

Predefined exceptions

Predefined exceptions are named conditions built into the database. PolarDB supports all native PostgreSQL predefined exceptions and the most common Oracle predefined exceptions, so you can use either style in a WHEN clause.

Raise an exception

Exceptions are raised in two ways:

  • Implicitly: a PL/SQL statement triggers an error at runtime

  • Explicitly: the RAISE statement raises a named exception

Implicitly raise by executing PL/SQL statements

-- Implicit: division by zero triggers an exception automatically
DECLARE
    result INT;
BEGIN
    result := 1 / 0;
END;

Explicitly raise with the RAISE statement

-- Explicit: PostgreSQL style
BEGIN
    RAISE division_by_zero;
END;

-- Explicit: Oracle style
BEGIN
    RAISE zero_divide;
END;

Catch an exception

Place an EXCEPTION section at the end of a BEGIN...END block to catch errors. When an exception is raised:

  1. Execution of the statements in the block stops immediately.

  2. Control passes to the EXCEPTION section, which searches for the first matching WHEN clause.

  3. If a match is found, the corresponding handler runs, and then execution continues after END.

  4. If no match is found, the exception propagates to the enclosing block. If there is no enclosing block, the subprogram aborts.

Use a named WHEN clause to catch a specific exception, or WHEN OTHERS to catch anything not already handled.

Catch a specific exception by name

-- Catch a specific exception: PostgreSQL style
DECLARE
    result INT;
BEGIN
    result := 1 / 0;
EXCEPTION
    WHEN division_by_zero THEN
        DBMS_OUTPUT.PUT_LINE('division by zero');
END;

-- Catch a specific exception: Oracle style
DECLARE
    result INT;
BEGIN
    result := 1 / 0;
EXCEPTION
    WHEN zero_divide THEN
        DBMS_OUTPUT.PUT_LINE('zero divide');
END;

Catch all exceptions with WHEN OTHERS

-- Catch all exceptions
DECLARE
    result INT;
BEGIN
    result := 1 / 0;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('division by zero');
END;

Non-predefined exceptions

Oracle defines many error codes that have no built-in name. To handle these by name, declare an exception variable and associate it with an Oracle error code using PRAGMA EXCEPTION_INIT.

Follow these three steps:

  1. In the DECLARE section, declare an exception variable:

    my_exception EXCEPTION;
  2. Bind the variable to a specific SQLCODE using PRAGMA EXCEPTION_INIT:

    Important

    The error code must be 100 (for the no_data_found exception) or a negative integer in the range -1000000 to -1. Only the range -65535 to -1 maps to valid Oracle SQLCODEs.

    PRAGMA EXCEPTION_INIT(my_exception, -1476);
  3. In the EXCEPTION section, catch the exception by name or with WHEN OTHERS:

    WHEN my_exception THEN
        ...

Example

DECLARE
    result INT;
    my_exception EXCEPTION;
    PRAGMA EXCEPTION_INIT(my_exception, -66666);
BEGIN
    result := 1 / 0;
EXCEPTION
    WHEN my_exception THEN
        DBMS_OUTPUT.PUT_LINE('zero divide');
END;

User-defined exceptions

Oracle reserves the error code range -20999 to -20000 for user-defined exceptions. Use RAISE_APPLICATION_ERROR to raise a custom error with a specific code and message from within this range.

Example

DECLARE
    salary NUMBER := 4000;
BEGIN
    IF salary < 5000 THEN
        RAISE_APPLICATION_ERROR(-20001, 'Salary is below the allowed minimum.');
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('Custom Error: ' || SQLERRM);
END;

Error codes and messages

Inside an EXCEPTION section, three built-in variables provide information about the error:

VariableTypeDescription
SQLSTATEFive-character stringNative PostgreSQL error code. The first two characters identify the error class.
SQLCODEIntegerOracle-compatible error code. Values: 100 (no_data_found), -65535 to -1 (standard Oracle errors), or -99999 (unsupported scenario in PolarDB for PostgreSQL (Compatible with Oracle)).
SQLERRMStringDetailed description of the error.

Example

DECLARE
    result INT;
BEGIN
    result := 1 / 0;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('SQLSTATE: ' || SQLSTATE);
        DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
END;

The output is:

SQLCODE: -1476
SQLSTATE: 22012
SQLERRM: division by zero

Named exceptions quick reference

The following table lists the Oracle exception names supported in PolarDB. Use this table when writing WHEN clauses to confirm which names are available.

Oracle exception nameSQLCODEError description
NO_DATA_FOUND100Query returned no results
DUP_VAL_ON_INDEX-1Unique constraint violation on insert
INVALID_CURSOR-1001Cursor is undefined or the cursor name is invalid
TOO_MANY_ROWS-1422Query returned too many rows
ZERO_DIVIDE-1476Division by zero
INVALID_NUMBER-1722Invalid TO_NUMBER function parameter
VALUE_ERROR-6502Invalid numeric format or value exceeds the upper limit
CURSOR_ALREADY_OPEN-6511Cursor is defined or opened multiple times
COLLECTION_IS_NULL-6531Collection is empty
SUBSCRIPT_OUTSIDE_LIMIT-6532Array index out of bounds
SUBSCRIPT_BEYOND_COUNT-6533Array index out of bounds
CASE_NOT_FOUND-6592CASE statement has no matching WHEN clause

Error code mapping

The following table maps all supported Oracle-style SQLCODEs to their PostgreSQL equivalents. Use this table to cross-reference error codes when debugging or writing error handlers that need to handle both styles.

Oracle exception nameSQLCODESQLSTATEPostgreSQL exception nameError description
NO_DATA_FOUND100P0002no_data_foundQuery returned no results
DUP_VAL_ON_INDEX-123505unique_violationUnique constraint violation on insert
-5455P03lock_not_availableLock acquisition failed
-93954023too_many_argumentsToo many function arguments
-95742701duplicate_columnDuplicate column name
-96042702ambiguous_columnAmbiguous column name
INVALID_CURSOR-100134000invalid_cursor_nameCursor is undefined or the cursor name is invalid
-103142501insufficient_privilegeInsufficient permissions
TOO_MANY_ROWS-1422P0003too_many_rowsQuery returned too many rows
-14282201Einvalid_argument_for_logarithmInvalid log function parameter
-14282201Finvalid_argument_for_power_functionInvalid power function parameter
ZERO_DIVIDE-147622012division_by_zeroDivision by zero
-1578XX001data_corruptedData corruption
-182122007invalid_datetime_formatDate format error
INVALID_NUMBER-1722Invalid TO_NUMBER function parameter
-1723Column length is 0
-1724Invalid FLOAT type precision
-1727Invalid NUMBER type precision
-312508P01protocol_violationCommunication protocol error
-402040P01deadlock_detectedDeadlock detected
-603553000insufficient_resourcesInsufficient resources
-611353300too_many_connectionsToo many connections
VALUE_ERROR-6502Invalid numeric format or value exceeds the upper limit
-65032F005function_executed_no_return_statementFunction has no RETURN statement
-6508Package function undefined
CURSOR_ALREADY_OPEN-651142P03duplicate_cursorCursor is defined or opened multiple times
COLLECTION_IS_NULL-65312203Gcollection_is_nullCollection is empty
SUBSCRIPT_OUTSIDE_LIMIT-65322202Earray_subscript_errorArray index out of bounds
SUBSCRIPT_BEYOND_COUNT-65332203Hsubscript_beyond_countArray index out of bounds
CASE_NOT_FOUND-659220000case_not_foundCASE statement has no matching WHEN clause
-24381P0005forall_dml_errorFORALL statement error
-2710253200out_of_memoryInsufficient memory
-3011042601syntax_errorSyntax error
-3015653100disk_fullDisk full
-99999Current scenario not supported