모든 산업 솔루션에서 SQL은 오류 처리 아키텍처가 잘 갖춰져야 합니다. 로깅 및 세심한 예외 처리가 없으면 특히 저장 프로시저 및 배치 스크립트에서 복잡한 프로세스를 디버깅할 수 없습니다.
문제 이력: 표준 SQL은 최소한의 오류 처리를 허용합니다 (예: RETURN 및 처리 중단). 현대의 확장 언어(T-SQL, PL/pgSQL, PL/SQL 등)는 오류 처리에 대한 완벽한 구조(TRY/CATCH, EXCEPTION)를 제공합니다.
문제: 명시적인 오류 처리가 없으면 "빠져버리고", 관리자는 특히 대량 변경이나 외부 시스템과의 작업 중 장애 원인을 파악하기 어렵습니다. 종종 나중에 분석하기 위해 별도의 테이블에 오류를 로깅해야 합니다.
해결책: TRY/CATCH(T-SQL) 또는 EXCEPTION(PL/pgSQL)의 무기를 사용하고, 자체 로깅 테이블을 활용하세요. 오류 코드, 오류 메시지, 쿼리 매개변수 및 시간을 로깅에 전송하는 것을 잊지 마십시오.
코드 예시 (T-SQL, MS SQL Server):
CREATE TABLE ErrorLog ( ErrorId INT IDENTITY PRIMARY KEY, ErrorTime DATETIME, ProcedureName NVARCHAR(128), ErrorMessage NVARCHAR(MAX), ErrorNumber INT, ErrorState INT, ErrorSeverity INT ); CREATE PROCEDURE usp_ProcessOrders AS BEGIN BEGIN TRY -- 비즈니스 로직 UPDATE Orders SET Status = 'PROCESSED' WHERE Status = 'NEW'; END TRY BEGIN CATCH INSERT INTO ErrorLog ( ErrorTime, ProcedureName, ErrorMessage, ErrorNumber, ErrorState, ErrorSeverity ) VALUES ( GETDATE(), ERROR_PROCEDURE(), ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY() ); THROW; END CATCH END
코드 예시 (PL/pgSQL, PostgreSQL):
BEGIN -- 귀하의 코드 EXCEPTION WHEN OTHERS THEN INSERT INTO error_log(ts, proc_name, err_text) VALUES(now(), 'my_proc', SQLERRM); RAISE; END;
주요 특징:
오류를 포착하고 정보를 외부로 전달하지 않고 프로시저의 실행을 종료하는 것으로 충분합니까?
아니요. 명시적인 로깅이나 오류 전파가 없으면 장애 원인을 포착하고 분석할 수 없습니다. 오류를 로그에 자세히 기록하거나 적어도 앞으로 전파하는 것이 중요합니다 (THROW/RAISE).
사용자 정의 프로시저에서 모든 오류를 식별하기 위해 SQL Server/DBMS 내장 로그만 사용할 수 있습니까?
부분적으로 가능합니다. 많은 오류가 응용 프로그램이나 프로시저에서 "잡아내" 처리되면 서버 로그에 기록되지 않습니다. 비즈니스 로직에서는 세부 사항을 포함한 이벤트 로그를 유지하는 것이 유용합니다.
간단한 DML 작업만 사용하는 프로시저에서 반드시 TRY/CATCH(또는 EXCEPTION)를 사용해야 합니까?
중요한 데이터에 영향을 미치고, 중대한 체인에서 참여하며 비정상적인 상황을 기록해야 하는 프로시저라면 꼭 필요합니다. "안전한" 작업조차도 외부 제약사항(고유성, FOREIGN KEY, 교착 상태 등)으로 인해 오류를 초래할 수 있습니다.
프로젝트에서 오류가 로깅되지 않고 사용자에게만 표시됩니다. 대량의 오류가 발생할 경우 관리자는 "보이지 않는" 문제를 찾기 위해 수 시간 동안 사라집니다.
장점:
단점:
모든 중요한 오류는 세부 사항(시간, 프로시저, 매개변수, 오류 코드)과 함께 로그 테이블에 기록되며, 시스템 티켓에 참조됩니다.
장점:
단점: