본문 바로가기
DataBase

MySQL 프로시저에서 예외 처리

by 대박플머 2024. 12. 9.

MySQL에서 프로시저(Stored Procedure)는 복잡한 데이터 처리 로직을 데이터베이스 내에서 미리 정의하고 이를 쉽게 호출할 수 있게 해주는 기능입니다. 그러나 프로시저를 작성할 때는 예외 상황에 대비하여 오류나 예외를 처리할 수 있는 메커니즘이 필요합니다. 특히 프로덕션 환경에서는 예기치 않은 오류가 발생할 수 있으므로 이를 처리하는 방법이 필수적입니다.

이번 글에서는 MySQL 프로시저에서의 예외 처리에 대해 설명하고, 다양한 예외 처리 기법을 소개하겠습니다.


예외 처리의 필요성

데이터베이스에서 실행되는 로직은 항상 예상대로 동작하지 않을 수 있습니다. 데이터의 무결성, 제약 조건 위반, 중복된 데이터 삽입, 외부 연결 문제 등 다양한 이유로 오류가 발생할 수 있습니다. 이런 상황에서 오류가 발생하더라도 적절한 오류 메시지를 제공하고, 시스템 전체에 영향을 주지 않도록 예외 처리를 통해 문제를 방지하는 것이 중요합니다.
MySQL은 이러한 오류를 처리하기 위해 HANDLER라는 구문을 제공합니다. HANDLER를 사용하면 특정 오류나 예외 상황이 발생했을 때 수행할 동작을 정의할 수 있습니다. 이때 사용되는 구문이 DECLARE ... HANDLER입니다.


예외 처리의 기본 구문

MySQL에서 예외를 처리하는 기본 구문은 다음과 같습니다:

DECLARE handler_action HANDLER FOR condition BEGIN ... END;
  • handler_action: 예외가 발생했을 때 수행할 동작을 정의합니다. 여기에는 주로 CONTINUE 또는 EXIT가 사용됩니다.
    • CONTINUE: 예외가 발생해도 계속해서 프로시저를 실행합니다.
    • EXIT: 예외가 발생하면 즉시 프로시저 실행을 종료합니다.
  • condition: 어떤 상황에서 예외 처리를 할 것인지를 정의합니다. 조건 명시자, SQLSTATE, MySQL 오류 코드 등을 사용할 수 있습니다.

예외 처리의 다양한 케이스

  1. NOT FOUND 예외 처리 NOT FOUNDSELECT 또는 FETCH 문이 결과를 반환하지 않았을 때 발생하는 예외입니다. 이는 주로 커서를 사용하는 반복문에서 자주 발생합니다.
DELIMITER $$

CREATE PROCEDURE getUser(IN userId INT)
BEGIN
    DECLARE CONTINUE HANDLER FOR NOT FOUND
    BEGIN
        -- 예외 처리 동작
        SELECT 'User not found!' AS ErrorMessage;
    END;

    -- 사용자 정보 조회
    SELECT * FROM Users WHERE id = userId;
END $$

DELIMITER ;

위 예시에서 getUser 프로시저는 특정 userId를 받아 해당 사용자의 정보를 조회합니다. 사용자가 존재하지 않을 경우, NOT FOUND 예외를 감지하여 'User not found!' 메시지를 반환하도록 처리합니다.2. 일반적인 SQL 오류 처리 (SQLEXCEPTION) SQLEXCEPTION은 모든 SQL 오류를 포괄적으로 처리할 수 있는 명령어입니다. 모든 SQL 오류에 대해 같은 예외 처리 동작을 지정하고자 할 때 유용합니다.

DELIMITER $$

CREATE PROCEDURE insertUser(IN userId INT, IN userName VARCHAR(100))
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
    BEGIN
        -- 예외 처리 동작
        SELECT 'An error occurred while inserting user!' AS ErrorMessage;
    END;

    -- 사용자 정보 삽입
    INSERT INTO Users (id, name) VALUES (userId, userName);
END $$

DELIMITER ;

이 프로시저는 Users 테이블에 새로운 사용자를 삽입합니다. 삽입 중에 발생할 수 있는 모든 SQL 오류를 처리하여, 중복된 키나 데이터 제약 위반 오류 등이 발생했을 때 SQLEXCEPTION으로 처리됩니다.3. 중복된 키 오류 처리 (1062 오류) MySQL에서 오류 코드 1062는 중복된 키를 삽입하려 할 때 발생하는 오류입니다. 이를 처리하려면 다음과 같이 HANDLER 구문에서 오류 코드를 지정할 수 있습니다.

DELIMITER $$

CREATE PROCEDURE insertUser(IN userId INT, IN userName VARCHAR(100))
BEGIN
    DECLARE CONTINUE HANDLER FOR 1062
    BEGIN
        -- 중복 키 오류 처리
        SELECT 'Duplicate key error!' AS ErrorMessage;
    END;

    -- 사용자 정보 삽입
    INSERT INTO Users (id, name) VALUES (userId, userName);
END $$

DELIMITER ;

위 예제에서 사용자는 중복된 ID를 삽입할 경우 'Duplicate key error!' 메시지를 받을 수 있습니다.
4. SQLSTATE를 사용한 특정 오류 처리
SQLSTATE는 5자리 코드로, MySQL에서 발생하는 다양한 예외를 구분할 수 있습니다. 특정 SQLSTATE 코드를 처리하는 방법도 있습니다.

DELIMITER $$

CREATE PROCEDURE updateUserAge(IN userId INT, IN userAge INT)
BEGIN
    IF userAge < 0 THEN
        -- 사용자 정의 예외 발생
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Age cannot be negative!';
    END IF;

    -- 사용자 나이 업데이트
    UPDATE Users SET age = userAge WHERE id = userId;
END $$

DELIMITER ;

위 코드에서 userAge가 0보다 작은 값이 들어올 경우, SIGNAL SQLSTATE 구문을 사용해 'Age cannot be negative!'라는 사용자 정의 오류를 발생시킵니다.5. 다중 조건 처리 여러 가지 조건을 동시에 처리할 수도 있습니다. 이를 위해 HANDLER FOR 구문에서 여러 조건을 나열할 수 있습니다.

DECLARE CONTINUE HANDLER FOR SQLWARNING, SQLEXCEPTION, NOT FOUND
BEGIN
    -- 예외 처리 동작
    SELECT 'A warning, exception, or not found situation occurred.' AS Message;
END;

이 예시에서는 경고(SQLWARNING), 예외(SQLEXCEPTION), 데이터 미발견(NOT FOUND) 상황을 동시에 처리할 수 있습니다. 각 상황에 따라 같은 예외 처리 로직을 적용할 수 있습니다.


사용자 정의 오류 발생: SIGNAL 구문MySQL에서는 SIGNAL 구문을 사용하여 프로시저 내부에서 명시적으로 오류를 발생시킬 수 있습니다. 이를 통해 조건에 맞는 사용자 정의 예외를 발생시키고, 이를 처리할 수 있습니다.

DELIMITER $$

CREATE PROCEDURE validateAndInsertUser(IN userName VARCHAR(100))
BEGIN
    IF CHAR_LENGTH(userName) < 3 THEN
        -- 사용자 정의 예외 발생
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Username must be at least 3 characters long!';
    END IF;

    -- 사용자 정보 삽입
    INSERT INTO Users (name) VALUES (userName);
END $$

DELIMITER ;

위 코드에서는 userName이 3자 미만일 경우 SIGNAL을 사용하여 사용자 정의 오류를 발생시킵니다. 이처럼 SIGNAL을 사용하면 비즈니스 로직에서 발생할 수 있는 다양한 오류 상황을 명시적으로 처리할 수 있습니다.


결론

MySQL 프로시저에서 예외 처리는 데이터베이스 로직의 신뢰성과 안정성을 보장하는 중요한 요소입니다. 프로시저를 사용할 때는 예상하지 못한 오류나 예외 상황이 언제든 발생할 수 있습니다. 이러한 상황에 대비해 적절한 예외 처리 구문을 미리 정의해 두면, 프로덕션 환경에서도 안전하게 시스템을 운영할 수 있습니다.
MySQL에서는 HANDLER, SIGNAL, 그리고 다양한 SQLSTATE와 MySQL 오류 코드를 활용하여 예외 처리를 세밀하게 설정할 수 있습니다. 예외 처리 전략을 잘 구축해 두면, 시스템의 안정성을 높이고 문제 발생 시 적절한 대응을 할 수 있는 환경을 만들 수 있습니다.