T-SQL 오류 처리 구현
오류는 데이터베이스 작업 중에 발생하는 문제 또는 주목할 만한 문제를 나타냅니다. 오류는 시스템 수준의 이벤트 또는 오류에 대한 응답으로 SQL Server 데이터베이스 엔진에서 생성할 수 있습니다. 또는 Transact-SQL 코드에서 애플리케이션 오류를 생성할 수 있습니다.
데이터베이스 엔진 오류의 요소
원인이 무엇이든 모든 오류는 다음 요소로 구성됩니다.
- 오류 번호 - 특정 오류를 식별하는 고유 번호입니다.
- 오류 메시지 - 오류를 설명하는 텍스트입니다.
- 심각도 - 1에서 25까지의 심각도의 숫자 표시입니다.
- 상태 - 데이터베이스 엔진 조건에 대한 내부 상태 코드입니다.
- 프로시저 - 오류가 발생한 저장 프로시저 또는 트리거의 이름입니다.
- 줄 번호 - 일괄 처리 또는 프로시저에서 오류를 생성한 문입니다.
시스템 오류
시스템 오류는 미리 정의되어 있으며 sys.messages 시스템 보기에서 볼 수 있습니다. 시스템 오류가 발생하면 SQL Server는 오류의 심각도에 따라 자동 수정 작업을 수행할 수 있습니다. 예를 들어 심각도가 높은 오류가 발생하면 SQL Server는 데이터베이스를 오프라인으로 전환하거나 데이터베이스 엔진 서비스를 중지할 수도 있습니다.
사용자 지정 오류
Transact-SQL 코드에서 오류를 생성하여 애플리케이션별 조건에 응답하거나 시스템 오류에 대응하여 클라이언트 애플리케이션에 전송된 정보를 사용자 지정할 수 있습니다. 이러한 애플리케이션 오류는 생성되는 인라인으로 정의하거나 시스템 제공 오류와 함께 sys.messages 테이블에서 미리 정의할 수 있습니다. 사용자 지정 오류에 사용되는 오류 번호는 50001 이상이어야 합니다.
sys.messages에 사용자 지정 오류 메시지를 추가하려면 sp_addmessage 사용합니다. 메시지의 사용자는 sysadmin 또는 serveradmin 고정 서버 역할의 멤버여야 합니다.
sp_addmessage 구문입니다.
sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg'
[ , [ @lang= ] 'language' ]
[ , [ @with_log= ] { 'TRUE' | 'FALSE' } ]
[ , [ @replace= ] 'replace' ]
다음은 이 구문을 사용하는 사용자 지정 오류 메시지의 예입니다.
sp_addmessage 50001, 10, N’Unexpected value entered’;
또한 사용자 지정 오류 메시지를 정의할 수 있습니다. sysadmin 서버 역할의 멤버는 추가 매개 변수 @with_log 사용할 수도 있습니다. TRUE로 설정하면 Windows 애플리케이션 로그에도 오류가 기록됩니다. Windows 애플리케이션 로그에 기록된 모든 메시지는 SQL Server 오류 로그에도 기록됩니다. 네트워크 및 시스템 관리자는 시스템 로그에서 "번잡한" 애플리케이션을 싫어하는 경향이 있으므로 이 옵션을 사용하는 @with_log 데 주의해야 합니다. 그러나 오류를 경고로 잡아야 하는 경우, 먼저 Windows 애플리케이션 로그에 오류를 기록해야 합니다.
비고
시스템 오류 제기는 지원되지 않습니다.
= 'replace' 옵션을 사용하여 @replace 메시지를 먼저 삭제하지 않고 바꿀 수 있습니다.
메시지는 사용자 지정할 수 있으며 language_id 값에 따라 여러 언어에 대해 동일한 오류 번호에 대해 다른 메시지를 추가할 수 있습니다.
비고
영어 메시지는 language_id 1033입니다.
RAISERROR를 사용하여 오류 발생
PRINT 및 RAISERROR는 모두 애플리케이션에 정보 또는 경고 메시지를 반환하는 데 사용할 수 있습니다. RAISERROR를 사용하면 애플리케이션이 호출 프로세스에 의해 포착될 수 있는 오류를 발생시킬 수 있습니다.
RAISERROR
T-SQL에서 오류를 발생시키는 기능을 사용하면 다른 시스템 오류처럼 전송되므로 애플리케이션에서 오류를 더 쉽게 처리할 수 있습니다. RAISERROR는 다음을 위해 사용됩니다.
- T-SQL 코드 문제를 해결하는 데 도움을 주세요.
- 데이터의 값을 확인합니다.
- 변수 텍스트가 포함된 메시지를 반환합니다.
비고
PRINT 문을 사용하는 것은 심각도 10의 오류를 발생시키는 것과 유사합니다.
다음은 RAISERROR를 사용하는 사용자 지정 오류 메시지의 예입니다.
RAISERROR (N'%s %d', -- Message text,
10, -- Severity,
1, -- State,
N'Custom error message number',
2)
트리거되면 다음을 반환합니다.
Custom error message number 2
이전 예제에서 %d 숫자의 자리 표시자이며 %s 문자열의 자리 표시자입니다. 또한 메시지 번호는 언급되지 않았습니다. 이 구문을 사용하여 메시지 문자열 오류가 발생하는 경우 오류 번호는 항상 50000입니다.
THROW를 사용하여 오류 발생
THROW 문은 코드에서 오류를 발생시키는 간단한 방법을 제공합니다. 오류의 오류 수는 50000 이상이어야 합니다.
THROW
THROW는 여러 가지 방법으로 RAISERROR와 다릅니다.
- THROW에서 발생한 오류는 항상 심각도 16입니다.
- THROW에서 반환된 메시지는 sys.sysmessages의 항목과 관련이 없습니다.
- THROW에서 발생한 오류는 SET XACT_ABORT ON과 함께 사용할 때만 트랜잭션이 중단되고 세션이 종료됩니다.
THROW 50001, 'An Error Occured',0
@@Error 사용하여 오류 코드 캡처
SQL Server 애플리케이션에서 가장 일반적인 오류 처리 코드는 @@ERROR 사용하여 만들어졌습니다. 구조적 예외 처리는 SQL Server 2005에서 도입되었으며 @@ERROR 사용하는 강력한 대안을 제공합니다. 다음 단원에서 설명합니다. 많은 양의 기존 SQL Server 오류 처리 코드는 @@ERROR 기반으로 하므로 이를 사용하는 방법을 이해하는 것이 중요합니다.
오류 발생
@@ERROR 발생한 마지막 오류의 오류 번호를 보유하는 시스템 변수입니다. @@ERROR 한 가지 중요한 과제는 각 추가 문이 실행될 때 보유하는 값이 빠르게 다시 설정된다는 것입니다.
예를 들어 다음 코드를 고려합니다.
RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO
코드가 실행되면 인쇄된 문자열에 오류 번호가 반환될 것으로 예상할 수 있습니다. 그러나 코드가 실행되면 다음을 반환합니다.
Msg 50000, Level 16, State 1, Line 1
Message
Error=0
오류가 발생했지만 인쇄된 메시지는 "Error=0"입니다. 출력의 첫 번째 줄에서 예상대로 오류가 실제로 50000인 것을 볼 수 있으며 메시지는 RAISERROR로 전달됩니다. RAISERROR 문 다음에 오는 IF 문이 성공적으로 실행되어 @@ERROR 값이 다시 설정되었기 때문입니다. 이러한 이유로 @@ERROR 작업할 때 오류 번호가 발생하는 즉시 변수로 캡처한 다음 변수로 처리를 계속하는 것이 중요합니다.
이를 보여 주는 다음 코드를 살펴봅니다.
DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));
이 코드가 실행되면 다음 출력이 반환됩니다.
Msg 50000, Level 16, State 1, Line 2
Message
Error=50000
오류 번호가 지금 올바르게 보고됩니다.
오류 처리 중앙 집중화
오류 처리에 @@ERROR 사용할 때 발생하는 다른 중요한 문제는 T-SQL 코드 내에서 중앙 집중화하기 어렵다는 점입니다. 오류 처리는 코드 전체에 분산되는 경향이 있습니다. 레이블 및 GOTO 문을 사용하여 @@ERROR 사용하여 오류 처리를 어느 정도 중앙 집중화할 수 있습니다. 그러나, 이것은 가난한 코딩 관행으로 오늘날 대부분의 개발자에 의해 눈살을 찌푸리게 될 것입니다.
오류 경고 만들기
특정 오류 범주의 경우 관리자가 SQL Server 경고를 만들 수 있습니다. 이러한 경고가 발생하는 즉시 알림을 받을 수 있기 때문입니다. 사용자 정의 오류 메시지에도 적용할 수 있습니다. 예를 들어 트랜잭션 로그가 채워질 때마다 경고를 발생시키고 싶을 수 있습니다. 경고는 일반적으로 관리자의 주의에 높은 심각도 오류(예: 심각도 19 이상)를 가져오는 데 사용됩니다.
경고 발생
특정 오류 메시지에 대한 경고를 만들 수 있습니다. 경고 서비스는 자신을 이벤트 로깅 서비스에 콜백 서비스로 등록하여 작동합니다. 즉, 경고는 기록된 오류에서만 작동합니다.
오류를 발생시키는 방법에는 두 가지가 있습니다. 오류를 발생시킬 때 WITH LOG 옵션을 사용하거나 메시지를 변경하여 sp_altermessage 실행하여 기록할 수 있습니다. WITH LOG 옵션은 현재 문에만 영향을 줍니다. sp_altermessage 사용하면 향후 모든 사용에 대한 오류 동작이 변경됩니다. sp_altermessage 통해 시스템 오류를 수정하는 것은 SQL Server 2005 SP3 또는 SQL Server 2008 SP1 이상에서만 가능합니다.