Structured error handling that traps runtime exceptions within a SQL block and routes execution to a handler.

Exception handling block that catches errors in the enclosed SQL or procedural code and lets execution continue. Different syntax across databases: EXCEPTION WHEN OTHERS (Oracle/PostgreSQL), TRY...CATCH (SQL Server/MySQL). Essential for robust stored procedures.

Compatibility

Show:
Database System Support Status Since Version Notes
MySQL ✓ Supported 5.5 Uses DECLARE ... HANDLER syntax inside stored procedures/functions; no bare TRY/CATCH block outside a routine.
PostgreSQL ✓ Supported 8.0 BEGIN/EXCEPTION block is available inside PL/pgSQL functions and DO blocks only; not in plain SQL.
SQL Server ✓ Supported 2005 TRY/CATCH works in ad-hoc batches, procedures, and triggers. Use ERROR_MESSAGE(), ERROR_NUMBER() inside the CATCH block.
Oracle ✓ Supported 7 PL/SQL EXCEPTION section is part of every block (anonymous or named). Uses named exception types or WHEN OTHERS.
SQLite ✗ Not Supported No procedural error-handling blocks. Applications must inspect return codes via the host language API.

Details

Structured error handling is universally available but the syntax varies significantly. SQL Server's TRY/CATCH is the closest to a general-purpose mechanism because it works in plain batch scripts; the others require a procedural language context (PL/pgSQL, PL/SQL, MySQL stored routines). In PostgreSQL, RAISE EXCEPTION re-throws; in Oracle, RAISE re-raises the current exception. All engines except SQLite expose error code and message via engine-specific functions (SQLERRM, ERROR_MESSAGE(), etc.). A common portability trap: SQL Server's TRY/CATCH does not catch compile-time errors or certain severity-20+ errors; use XACT_STATE() to check transaction validity inside the CATCH block.

Standard Syntax

BEGIN TRY -- risky statement END TRY BEGIN CATCH -- handle error END CATCH;

Version Support

MySQL: Since 5.5 PostgreSQL: Since 8.0 SQL Server: Since 2005 Oracle: Since 7 SQLite: Not supported

Per-Database Syntax & Notes

MySQL

Uses DECLARE ... HANDLER syntax inside stored procedures/functions; no bare TRY/CATCH block outside a routine.

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 @msg = MESSAGE_TEXT; END;

PostgreSQL

BEGIN/EXCEPTION block is available inside PL/pgSQL functions and DO blocks only; not in plain SQL.

DO $$ BEGIN -- risky EXCEPTION WHEN others THEN RAISE NOTICE 'error: %', SQLERRM; END; $$;

SQL Server

TRY/CATCH works in ad-hoc batches, procedures, and triggers. Use ERROR_MESSAGE(), ERROR_NUMBER() inside the CATCH block.

BEGIN TRY INSERT INTO t VALUES (1); END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH;

Oracle

PL/SQL EXCEPTION section is part of every block (anonymous or named). Uses named exception types or WHEN OTHERS.

BEGIN INSERT INTO t VALUES (1); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('duplicate'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); END;