⚙️ MSSQL RAISERROR 사용법과 실전 예제
📌 트랜잭션 중단과 로그 기록까지 가능한 RAISERROR 활용 가이드
데이터베이스 개발이나 유지보수를 하다 보면, 특정 조건에서 쿼리 실행을 강제로 멈추거나 오류 메시지를 사용자나 로그에 남겨야 하는 상황이 자주 발생합니다.
이때 유용하게 활용할 수 있는 기능이 바로 RAISERROR입니다.
RAISERROR는 단순히 오류를 발생시키는 것에 그치지 않고, 심각도 수준을 지정하거나 사용자 정의 메시지를 출력할 수 있어 상황에 맞는 대응이 가능합니다.
이 글에서는 MSSQL에서 RAISERROR를 어떻게 사용하고, 어떤 경우에 효과적인지 실무 예제와 함께 자세히 알려드리겠습니다.
특히, 트랜잭션 처리 과정에서 조건에 맞지 않는 데이터가 입력되거나, 중요한 비즈니스 규칙이 위반될 경우 RAISERROR를 활용해 즉시 실행을 중단하고 오류를 기록할 수 있습니다.
또한, SQL Server의 오류 로그 또는 애플리케이션 로그와 연동해 운영 환경에서도 문제를 신속히 파악할 수 있도록 돕습니다.
아래 목차를 통해 RAISERROR의 기본 개념부터 심화 활용법까지 단계별로 살펴보겠습니다.
📋 목차
⚙️ RAISERROR 기본 개념과 동작 원리
MSSQL에서 RAISERROR는 데이터베이스 실행 과정에서 사용자 정의 오류 메시지를 발생시키는 명령문입니다.
기본적으로 오류를 발생시키고, 심각도(severity)와 상태(state)를 지정하여 메시지를 SQL Server나 애플리케이션에 전달할 수 있습니다.
이 기능을 활용하면 개발자는 단순히 에러를 알리는 것뿐 아니라, 오류 처리 흐름을 제어하고 문제 상황을 정확하게 로깅할 수 있습니다.
RAISERROR는 두 가지 주요 용도로 쓰입니다.
첫째, 트랜잭션 중단입니다.
조건문이나 예외 상황에서 RAISERROR를 실행하면, 해당 트랜잭션이 즉시 중단되며 이후 명령이 실행되지 않습니다.
둘째, 로그 기록입니다.
오류 메시지를 SQL Server 로그 또는 애플리케이션 로그로 남겨, 운영 환경에서 장애 원인을 추적할 수 있게 합니다.
💡 RAISERROR와 THROW의 차이
SQL Server 2012 이후부터는 THROW라는 새로운 예외 처리 명령이 추가되었습니다.
RAISERROR와 THROW 모두 오류를 발생시키지만, THROW는 구문이 간결하고 TRY…CATCH 블록 안에서 예외를 다시 발생시키는 데 유리합니다.
반면 RAISERROR는 SQL Server 2008 등 구버전에서도 사용할 수 있으며, 심각도 지정과 사용자 정의 메시지 ID 활용이 가능합니다.
-- 기본 RAISERROR 구문 예제
RAISERROR ('오류가 발생했습니다.', 16, 1);
💡 TIP: RAISERROR의 두 번째 인자인 심각도(severity)는 0~25까지 지정 가능하며, 11 이상이면 오류로 인식됩니다. 20 이상이면 연결이 끊어질 수 있으므로 주의해야 합니다.
🛠️ RAISERROR 구문 구조와 주요 매개변수
RAISERROR는 다음과 같은 기본 구문 구조를 가지고 있습니다.
이 구조를 이해하면 다양한 상황에서 유연하게 적용할 수 있습니다.
RAISERROR (message_string | message_id, severity, state
[ , argument [ , ...n ] ] )
[ WITH option [ , ...n ] ]
🔍 주요 매개변수 설명
| 매개변수 | 설명 |
|---|---|
| message_string | 직접 작성하는 오류 메시지 문자열입니다. |
| message_id | sys.messages에 등록된 사용자 정의 메시지 ID입니다. |
| severity | 오류의 심각도를 나타내며, 0~25 사이의 값을 가집니다. |
| state | 오류 상태를 나타내며 0~255까지 지정 가능합니다. |
⚙️ WITH 옵션
WITH 옵션을 사용하면 RAISERROR의 동작 방식을 더 세부적으로 제어할 수 있습니다.
대표적인 옵션은 다음과 같습니다.
- 📝WITH LOG – 오류 메시지를 SQL Server 오류 로그와 Windows 이벤트 뷰어에 기록
- 🚫WITH NOWAIT – 버퍼링 없이 즉시 메시지를 클라이언트에 전송
⚠️ 주의: WITH LOG 옵션을 사용할 경우, SQL Server에서 sysadmin 또는 serveradmin 권한이 필요합니다.
💡 사용자 정의 오류 메시지 등록과 호출
운영 환경에서는 표준 오류만으로는 원인 파악이 어렵거나, 비즈니스 규칙을 명확히 전달하기에 부족할 때가 많습니다.
이럴 때 사용자 정의 오류 메시지를 등록하면, 일관된 문구와 번호 체계를 갖추어 신속한 진단과 로그 분석이 가능합니다.
MSSQL에서는 sys.sp_addmessage로 메시지를 등록하고, RAISERROR에서 메시지 ID를 사용해 호출합니다.
또한 서식 매개변수로 동적인 값을 메시지에 삽입해, 현장 상황을 구체적으로 남길 수 있습니다.
🧱 sys.sp_addmessage로 메시지 등록
메시지는 데이터베이스가 아닌 서버 범위로 관리되며, 보통 50000 이상 번호 대역을 사용합니다.
메시지 텍스트에는 %s, %d 같은 서식 지정자를 포함할 수 있습니다.
언어별 메시지를 별도로 등록할 수도 있어 다국어 운영에 유리합니다.
-- 사용자 정의 메시지 등록
EXEC sys.sp_addmessage
@msgnum = 50001, -- 50000 이상 권장
@severity = 16, -- 사용자 오류 범주
@msgtext = N'잘못된 주문 번호입니다. 주문번호: %d',
@lang = N'ko-KR',
@with_log = 'false', -- 기본은 로그 미기록
@replace = 'replace'; -- 기존 텍스트가 있으면 교체
⚠️ 주의: 50000 미만 번호는 시스템 용도로 예약되어 충돌 위험이 있습니다.
조직 표준에 맞춰 50000 이상에서 범위를 할당해 사용하세요.
🧩 RAISERROR로 메시지 호출과 매개변수 전달
등록된 메시지는 message_id를 사용해 호출합니다.
서식 지정자가 있다면 추가 인자로 값을 전달합니다.
심각도와 상태값을 적절히 부여해 오류 처리 흐름을 통제합니다.
DECLARE @OrderId INT = 12345;
RAISERROR (50001, 16, 1, @OrderId); -- 결과: "잘못된 주문 번호입니다. 주문번호: 12345"
💡 TIP: 동일 메시지를 다양한 상황에 재사용하려면 변수나 컬럼 값을 서식 인자로 전달하세요.
메시지 텍스트는 고정하되, 로그엔 매번 다른 컨텍스트가 남습니다.
🧭 로그 정책: WITH LOG와 sp_altermessage
특정 메시지는 항상 서버 오류 로그에 남기고 싶을 때가 있습니다.
두 가지 방법이 있습니다.
첫째, 호출 시 WITH LOG 옵션을 사용합니다.
둘째, sys.sp_altermessage로 메시지 자체를 로그 강제 기록 대상으로 지정합니다.
-- 1) 호출 시 로그 기록
RAISERROR (50001, 16, 1, @OrderId) WITH LOG;
-- 2) 메시지를 항상 로그로
EXEC sys.sp_altermessage
@message_id = 50001,
@parameter = 'WITH_LOG',
@parameter_value = 'true';
⚠️ 주의: 로그 강제 기록 설정과 WITH LOG 사용에는 권한 요건이 따릅니다.
대개 sysadmin 또는 적절한 서버 수준 권한이 필요하니 운영 정책을 확인하세요.
🔎 등록된 메시지 조회·수정·삭제
메시지 현황은 sys.messages 뷰에서 확인합니다.
텍스트 변경은 @replace = ‘replace’로 sp_addmessage를 다시 실행하거나, 필요 시 메시지 삭제 후 재등록합니다.
-- 조회
SELECT message_id, language_id, severity, is_event_logged, text
FROM sys.messages
WHERE message_id = 50001;
-- 삭제
EXEC sys.sp_dropmessage @msgnum = 50001, @lang = N'ko-KR';
- 🗂️메시지 번호, 심각도, 언어별 등록 현황을 정기 점검하세요.
- 🧩서식 지정자는 실제 전달 인자 수와 타입을 맞춰 런타임 오류를 방지하세요.
- 🛡️운영 반영 전 테스트 환경에서 로그 정책과 TRY…CATCH 동작을 검증하세요.
🚫 트랜잭션 중단 및 ROLLBACK과의 연계
MSSQL에서 RAISERROR를 가장 강력하게 활용하는 방법 중 하나는 트랜잭션과 연계하는 것입니다.
비즈니스 로직 실행 도중 조건이 충족되지 않거나, 데이터 무결성이 훼손될 가능성이 감지되면 즉시 오류를 발생시키고 ROLLBACK을 통해 이전 상태로 되돌릴 수 있습니다.
이를 통해 잘못된 데이터 반영을 사전에 차단하고, 시스템 안정성을 확보할 수 있습니다.
🔄 기본 트랜잭션 흐름 예제
BEGIN TRY
BEGIN TRANSACTION;
-- 데이터 처리 로직
IF EXISTS (SELECT 1 FROM Orders WHERE Quantity <= 0)
BEGIN
RAISERROR('수량이 0 이하인 주문이 존재합니다.', 16, 1);
END
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
-- 오류 정보 확인
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH
💡 TIP: RAISERROR를 TRY…CATCH 블록과 함께 사용하면 오류 발생 시 ROLLBACK과 추가 로깅을 자동화할 수 있습니다.
⚠️ 주의할 점
- 🚫RAISERROR 발생 시점 이후의 코드가 실행되지 않으므로, 커넥션 종료나 로그 저장 로직은 CATCH 블록에 배치해야 합니다.
- 🛡️ROLLBACK 후에도 연결은 유지되므로, 필요한 경우 세션 종료나 재연결 절차를 포함하세요.
- 📜운영 환경에서는 ROLLBACK 직전 상태를 별도 테이블에 기록하는 로직을 권장합니다.
🧩 RAISERROR와 조건부 ROLLBACK
모든 오류 상황에서 ROLLBACK을 수행할 필요는 없습니다.
일부 경고성 메시지는 트랜잭션을 유지한 채 로그만 남기는 것이 더 유리할 수 있습니다.
심각도(severity)를 10 이하로 설정하면 경고성 메시지로만 처리되며, 트랜잭션은 계속 유지됩니다.
IF (@재고수량 < @최소허용치)
BEGIN
RAISERROR('재고가 부족합니다. 현재 수량: %d', 10, 1, @재고수량) WITH LOG;
END
⚠️ 주의: 경고성 메시지를 남긴 뒤에도 트랜잭션이 계속 진행되므로, 이후 로직에서 동일 조건을 다시 점검하는 방어 로직이 필요합니다.
📊 운영 환경에서의 로그 기록 활용법
RAISERROR를 단순히 오류 알림 용도로만 사용하는 것은 아깝습니다.
운영 환경에서는 로그 기록 기능을 적극적으로 활용하여 장애 대응 속도를 높이고, 문제 재발을 방지할 수 있습니다.
특히 WITH LOG 옵션과 Windows 이벤트 뷰어 연계를 통해 DB 관리자와 시스템 운영팀이 동일한 정보를 공유할 수 있습니다.
📝 SQL Server 오류 로그와의 연계
WITH LOG 옵션을 사용하면 RAISERROR 메시지가 SQL Server 오류 로그와 Windows 이벤트 뷰어에 동시에 기록됩니다.
이 방식은 운영 장애 분석에 매우 효과적이며, 보안 및 컴플라이언스 요구사항을 충족하는 데 도움이 됩니다.
RAISERROR('중요 오류 발생: %s', 16, 1, @오류내용) WITH LOG;
📂 애플리케이션 로그와 통합
웹 애플리케이션이나 ERP 시스템에서는 RAISERROR를 발생시킨 후, CATCH 블록에서 애플리케이션 로그 파일이나 중앙 로깅 서버(예: ELK Stack, Splunk)에 기록할 수 있습니다.
이를 통해 DB 이벤트와 애플리케이션 이벤트를 연결하여 전사적인 모니터링 체계를 구축할 수 있습니다.
- 🔗DB와 애플리케이션 로그를 동일 타임스탬프로 기록해 사건 추적을 용이하게 함
- 📡중앙 로깅 서버를 활용해 실시간 대시보드와 경고 알림 설정
- 🛡️로그 접근 권한을 최소화하여 민감 정보 유출 방지
📊 운영 리포트 자동화
로그 데이터를 주기적으로 수집해 운영 리포트를 자동 생성하면, 관리자와 경영진이 서비스 안정성을 빠르게 파악할 수 있습니다.
Power BI, Tableau 같은 시각화 도구를 활용하면 오류 발생 빈도, 유형, 영향 범위를 직관적으로 확인할 수 있습니다.
💎 핵심 포인트:
RAISERROR 로그를 단순 저장이 아니라 데이터 자산으로 활용하면, 예측 유지보수와 품질 개선까지 연결할 수 있습니다.
⚠️ 로그 관리 시 주의사항
- 🧹불필요하게 오래된 로그는 주기적으로 정리하여 저장 공간 확보
- 🔒로그 파일에 포함된 개인정보는 암호화 또는 마스킹 처리
- 📑로그 보존 정책을 사전에 문서화하여 법적 요구사항 준수
❓ 자주 묻는 질문 (FAQ)
RAISERROR와 THROW 중 어떤 것을 사용해야 하나요?
RAISERROR 심각도(severity)는 어떻게 설정하나요?
WITH LOG 옵션은 언제 사용하나요?
사용자 정의 메시지는 어떻게 등록하나요?
ROLLBACK 없이 RAISERROR를 사용할 수 있나요?
RAISERROR 실행 후에도 코드가 계속 실행되나요?
운영 환경에서 RAISERROR 로그는 어디서 확인하나요?
RAISERROR 사용 시 성능에 영향이 있나요?
📌 RAISERROR 활용으로 안정적인 데이터베이스 운영하기
MSSQL의 RAISERROR는 단순한 오류 메시지 출력 도구를 넘어, 트랜잭션 제어와 로그 기록을 통한 운영 안정성 확보에 중요한 역할을 합니다.
심각도와 상태값을 지정해 다양한 수준의 오류를 처리할 수 있으며, 사용자 정의 메시지를 등록해 비즈니스 로직에 특화된 알림을 제공할 수 있습니다.
또한 WITH LOG 옵션과의 결합을 통해 장애 분석과 이력 관리까지 가능하므로, 운영 환경에서의 활용 가치가 높습니다.
이 글에서 소개한 기법들을 적용하면 데이터 무결성을 강화하고, 문제 발생 시 빠른 대응과 원인 분석이 가능해집니다.
개발 및 운영 환경 모두에서 RAISERROR를 전략적으로 사용하면 단순 오류 처리 이상의 가치를 창출할 수 있습니다.
특히 TRY…CATCH와의 연계, 조건부 ROLLBACK, 중앙 로그 서버와의 통합 등 다양한 패턴을 적용해보면 시스템 안정성과 가용성을 크게 높일 수 있습니다.
🏷️ 관련 태그 : MSSQL, RAISERROR, SQL서버오류처리, 데이터베이스트랜잭션, 사용자정의메시지, WITHLOG, TRY_CATCH, SQL개발팁, 운영DB관리, 로그분석