CodeGym /행동 /SQL SELF /에러 로깅: 로깅 레벨과 메시지 포맷

에러 로깅: 로깅 레벨과 메시지 포맷

SQL SELF
레벨 55, 레슨 2
사용 가능

지금 우리 완전 비밀 요원처럼 행동하는 거 알지? 우리 함수랑 프로시저들은 미션을 수행해: 데이터 처리하고, 계산하고, 아니면 그냥 데이터베이스 안에서 마법 부리기도 하고. 근데 뭔가 잘못되면 어떻게 알지? "데이터 마사지 욕조"가 어디서 망가졌는지 어떻게 파악해? 이럴 때 로깅이랑 에러 처리가 진짜 도움 돼.

기억나? PostgreSQL이랑 PL/pgSQL에서 어떻게 "소통"하고 로그 남기는지 이미 살짝 봤었잖아:

  • RAISE NOTICE: 완전 편안하고 친근한 느낌 — "야, 여기 다 괜찮은데, 혹시 궁금하면 한 번 봐봐~".
  • RAISE WARNING: 살짝 더 큰 목소리 — "어, 뭔가 이상한데? 한 번 확인해볼래?".
  • RAISE EXCEPTION: 완전 비상사이렌 — "멈춰! 알고리즘에 문제 생겼어! 더 망가지기 전에 실행 중단했어!".

이 각각의 레벨은 다 역할이 있으니까, 언제 뭘 써야 할지 잘 골라야 해.

이런 메시지들이 코드에서 어떻게 보이는지 한 번 볼까:

DO $$
BEGIN
    -- NOTICE 레벨 (다 괜찮고, 그냥 알림)
    RAISE NOTICE '그냥 알림: 데이터 처리 시작했어';

    -- WARNING 레벨 (뭔가 수상함)
    RAISE WARNING '경고: 컬럼 데이터 포맷이 이상할 수도 있음';

    -- EXCEPTION 레벨 (치명적 에러)
    RAISE EXCEPTION '에러: 입력값이 허용되지 않아!';
END $$;

언제 써야 하냐면:

  • RAISE NOTICE — 디버깅이나 편하게 정보 출력할 때.
  • RAISE WARNING — 데이터가 뭔가 잘못됐을 때 경고 주고 싶을 때.
  • RAISE EXCEPTION — 진짜 심각한 에러라서 함수 실행을 멈춰야 할 때.

RAISE EXCEPTION으로 에러 처리하기

RAISE EXCEPTION은 진짜 비상정지 버튼이야. 뭔가 잘못되면 함수 실행을 바로 멈추고 에러 메시지 남길 수 있어.

기본 사용법은 이렇게 생겼어:

RAISE EXCEPTION '너의 에러 메시지';

근데 메시지를 더 자세하게 만들고 싶으면 변수도 쓸 수 있어:

DECLARE
    input_value INTEGER;
BEGIN
    input_value := NULL;

    IF input_value IS NULL THEN
        RAISE EXCEPTION '에러: 입력값이 NULL이야. INTEGER 값이 필요해';
    END IF;
END;

메시지 포맷팅

메시지 안에 변수 바로 넣을 수도 있어:

DECLARE
    var1 TEXT := '데이터';
    var2 INTEGER := 42;
BEGIN
    RAISE EXCEPTION '처리 중 에러: % (ID %)', var1, var2;
END;

출력: 처리 중 에러: 데이터 (ID 42).

예시: 데이터 검증

예를 들어, 어떤 프로시저가 사람 나이를 받아. 나이가 음수면 당연히 에러 내야지:

CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
    IF age < 0 THEN
        RAISE EXCEPTION '나이는 음수일 수 없어: %', age;
    END IF;
END;
$$ LANGUAGE plpgsql;

-- 함수 호출
SELECT validate_age(-5);  -- 에러 발생

RAISE NOTICE로 알림 주기

RAISE EXCEPTION이 사이렌이라면, RAISE NOTICE는 그냥 어깨 툭툭 치는 느낌이야. 이 레벨로 함수 안에서 무슨 일이 일어나는지 설명하는 코멘트 남길 수 있어.

RAISE NOTICE 언제 쓰냐면:

  • 디버깅 정보 출력 (예: 변수 현재 값 등).
  • 단계 시작이나 계산 결과 알릴 때.

예시: 정보 메시지

CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    final_price NUMERIC;
BEGIN
    RAISE NOTICE '할인 전 가격: %', price;
    RAISE NOTICE '할인율: %', discount_rate;

    final_price := price - (price * discount_rate);

    RAISE NOTICE '최종 가격: %', final_price;

    RETURN final_price;
END;
$$ LANGUAGE plpgsql;

-- 함수 호출
SELECT calculate_discount(100, 0.2);
-- 출력:
-- NOTICE: 할인 전 가격: 100
-- NOTICE: 할인율: 0.2
-- NOTICE: 최종 가격: 80

실전 예시: 단계별 계획과 로깅

예를 들어, 복잡한 데이터 처리 프로시저가 있는데, 지금 어느 단계인지 알고 싶을 때:

CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
    RAISE NOTICE '1단계: 데이터 준비';
    -- 첫 번째 단계 로직

    RAISE NOTICE '2단계: 데이터 검증';
    -- 두 번째 단계 로직

    RAISE NOTICE '3단계: 데이터 저장';
    -- 세 번째 단계 로직
END;
$$ LANGUAGE plpgsql;

-- 함수 호출
SELECT process_data_step_by_step();
-- 로그에 단계별 실행이 표시됨

또 다른 예시도 있어. 상상해봐, 어떤 가게가 일정 금액 이상 주문에만 할인해준다고 하자:

CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    IF order_amount < 50 THEN
        RAISE EXCEPTION '에러: 주문 금액은 최소 50이어야 해, 현재 금액: %', order_amount;
    END IF;

    RETURN order_amount * 0.9;  -- 10% 할인 적용
END;
$$ LANGUAGE plpgsql;

-- 함수 호출
SELECT apply_discount(30);  -- 에러: 주문 금액은 최소 50이어야 해

흔한 실수들

실수 1: 파라미터 없이 메시지 로깅하기.

이렇게 하면 큰 프로시저에서 정보가 너무 부족해:

RAISE NOTICE '에러 발생';  -- 왜? 어디서? 어떻게?

추천: 항상 컨텍스트를 추가해:

RAISE NOTICE 'process_data() 함수에서 에러: 입력값: %', input_value;

실수 2: RAISE EXCEPTION을 RAISE WARNING만으로도 충분할 때 쓰는 것.

예외를 너무 남발하면 코드가 자꾸 멈춰서 데이터 처리하기 힘들어져.

팁: 로깅 레벨을 잘 생각해서 써. 디버깅엔 NOTICE, 진짜 중요한 순간엔 EXCEPTION!

실수 3: 아예 로깅을 안 하는 것.

이건 어두운 방에서 열쇠 찾는 거랑 똑같아. 로그 없으면 복잡한 프로세스 디버깅이 거의 불가능해져.

팁: 함수가 크고 복잡할수록 중요한 단계마다 RAISE NOTICE 꼭 추가해.

2
과제
SQL SELF, 레벨 55, 레슨 2
잠금
데이터 유효성 검사 시 오류 로깅하기
데이터 유효성 검사 시 오류 로깅하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION