SQL Error Handling — Catching and Responding to SQL Failures: BEGIN...HANDLER, SIGNAL

Handle SQL Errors

The office attempts to add a repeated roll number. Silently continuing could make the application claim a student was saved when the insert failed.

Database error handling determines how a program responds when an operation fails. A handler must match the intended condition and leave the data in an understood state.

  1. Explain and apply

    Handle an expected MySQL database error and explain what happens to the operation and transaction.

  2. Work it out

    Predict what remains after an insertion conflicts with the primary key. The original three rows should still be present.

  3. Avoid mistakes

    An EXIT handler does not by itself roll back the entire transaction.

Handle SQL Errors: the request and its result

  1. School need

    The office attempts to add a repeated roll number. Silently continuing could make the application claim a student was saved when the insert failed.

  2. Database operation

    Database error handling determines how a program responds when an operation fails. A handler must match the intended condition and leave the data in an understood state.

  3. Check the outcome

    The duplicate-key insert is rejected. This SQLite fixture verifies the constraint failure and surviving data; MySQL handler definitions in the preserved examples require a MySQL server.

A conceptual model. The query examples below show the actual syntax, input data and results.

Understand what the database does

MySQL DECLARE HANDLER associates conditions with a response. CONTINUE resumes after handling; EXIT leaves the declaring compound block. SIGNAL can raise an explicit application condition. A routine should distinguish expected exceptions from failures that require rollback or propagation.

Related concepts: Data Constraints and Transactions and Stored Procedures.

What is Error Handling in SQL?

Error handling allows you to catch and manage exceptions inside stored procedures or triggers using constructs like DECLARE HANDLER, SIGNAL, and RESIGNAL. These tools help you respond smartly instead of failing silently or abruptly.

Syntax Overview

  • DECLARE CONTINUE HANDLER – catches errors and continues
  • DECLARE EXIT HANDLER – catches errors and exits the block
  • SIGNAL SQLSTATE – manually raise a custom error

Sample Table – students

SQL · portable concepts; preserved examples identify their engine

CREATE TABLE students (
  roll_no INT PRIMARY KEY,
  name VARCHAR(50),
  marks INT
);

INSERT INTO students VALUES
(1, 'Aarav Sharma', 85),
(2, 'Diya Iyer', 92);

1. Handling Duplicate Entry Error (EXIT HANDLER)

SQL · portable concepts; preserved examples identify their engine

DELIMITER $$

CREATE PROCEDURE insert_student (
  IN p_roll INT,
  IN p_name VARCHAR(50),
  IN p_marks INT
)
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SELECT 'Error: Roll number already exists or invalid data.' AS message;
  END;

  INSERT INTO students VALUES (p_roll, p_name, p_marks);
END$$

DELIMITER ;

Test it:

CALL insert_student(1, 'Sneha Patil', 88);
message
---------------------------------------
Error: Roll number already exists or invalid data.

2. Handling Error and Continuing Execution (CONTINUE HANDLER)

SQL · portable concepts; preserved examples identify their engine

DELIMITER $$

CREATE PROCEDURE insert_and_continue ()
BEGIN
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
  BEGIN
    SELECT 'Attempted insert failed, moving on...' AS status;
  END;

  INSERT INTO students VALUES (1, 'Mehul', 75); -- Will fail
  SELECT * FROM students;
END$$

DELIMITER ;

Call it:

CALL insert_and_continue();
status
-------------------------------
Attempted insert failed, moving on...

roll_no | name           | marks
--------+----------------+-------
1       | Aarav Sharma   | 85
2       | Diya Iyer      | 92

3. Raising a Custom Error with SIGNAL

Input definitions and data for this example. The shown statements establish the base fixture. Where this section changes an existing object, its required object definition is included below; use the stated before/after table to follow a sequence of changes.

CREATE TABLE students (
  roll_no INT PRIMARY KEY,
  name VARCHAR(50),
  marks INT
);

INSERT INTO students VALUES
(1, 'Aarav Sharma', 85),
(2, 'Diya Iyer', 92);

SQL · portable concepts; preserved examples identify their engine

DELIMITER $$

CREATE PROCEDURE validate_marks (
  IN p_marks INT
)
BEGIN
  IF p_marks > 100 THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = 'Marks cannot exceed 100';
  END IF;

  SELECT CONCAT('Accepted: ', p_marks) AS status;
END$$

DELIMITER ;

Try invalid input:

CALL validate_marks(105);
ERROR 1644 (45000): Marks cannot exceed 100

Best Practices

Query discussed in this section:

CALL validate_marks(105);
  • Use EXIT HANDLER to stop on fatal errors.
  • Use CONTINUE HANDLER to skip errors but continue processing.
  • Use SIGNAL to enforce custom validation rules clearly.
  • Always log or alert on exceptions — don’t fail silently.

Real-World School Use Cases

  • Prevent marks from exceeding limits (custom SIGNAL)
  • Log failed insertions or updates (HANDLER + log table)
  • Auto-handle missing attendance records without breaking flows

Important differences and mistakes

An EXIT handler does not by itself roll back the entire transaction. A duplicate-key error is not equivalent to every integrity violation. Do not swallow an error and report success; decide explicitly which writes remain valid.

Try it with the school data

Predict what remains after an insertion conflicts with the primary key. The original three rows should still be present.

This practice uses a separate, fresh fixture named practice_students. It does not continue the changing table state of the earlier examples.

Practice input: practice_students
roll_nonameclassmarkscity
1Aarav10A85Pune
2Diya9B70Chennai
3Sneha10A85Pune

SQL · create only these practice tables in a disposable database:

CREATE TABLE practice_students (roll_no INTEGER PRIMARY KEY, name VARCHAR(50), class VARCHAR(10), marks INTEGER, city VARCHAR(30));
INSERT INTO practice_students VALUES
(1, 'Aarav', '10A', 85, 'Pune'),
(2, 'Diya', '9B', 70, 'Chennai'),
(3, 'Sneha', '10A', 85, 'Pune');

Worked answer and reasoning

This practice uses a separate, fresh fixture named practice_students. It does not continue the changing table state of the earlier examples.

Practice input: practice_students
roll_nonameclassmarkscity
1Aarav10A85Pune
2Diya9B70Chennai
3Sneha10A85Pune

SQL · create only these practice tables in a disposable database:

CREATE TABLE practice_students (roll_no INTEGER PRIMARY KEY, name VARCHAR(50), class VARCHAR(10), marks INTEGER, city VARCHAR(30));
INSERT INTO practice_students VALUES
(1, 'Aarav', '10A', 85, 'Pune'),
(2, 'Diya', '9B', 70, 'Chennai'),
(3, 'Sneha', '10A', 85, 'Pune');

SQL · this practice variation runs with SQLite 3; the preserved examples retain their stated dialect

INSERT INTO practice_students VALUES (1, 'Another student', '9B', 90, 'Delhi');
SELECT COUNT(*) AS student_rows FROM practice_students;
Expected query result
student_rows
3

The duplicate-key insert is rejected. This SQLite fixture verifies the constraint failure and surviving data; MySQL handler definitions in the preserved examples require a MySQL server.

The marked INSERT is expected to fail. Observe that error before running the following SELECT; do not report that the insert succeeded.

Check your understanding

Does declaring an EXIT HANDLER automatically roll back all earlier writes?
Choose one answer. You can try again.

Answer and explanation

No. Transaction cleanup must be chosen explicitly.

The duplicate-key insert is rejected. This SQLite fixture verifies the constraint failure and surviving data; MySQL handler definitions in the preserved examples require a MySQL server.

Use the idea independently

Database error handling determines how a program responds when an operation fails. A handler must match the intended condition and leave the data in an understood state.

The duplicate-key insert is rejected. This SQLite fixture verifies the constraint failure and surviving data; MySQL handler definitions in the preserved examples require a MySQL server.

Continue your understanding with Data Constraints and Transactions and Stored Procedures.

Source for the engine-specific behavior: MySQL 8.4 reference documentation.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Dynamic SQL — Building and Executing SQL on the Fly →