Transact-SQL의 오류 정보 검색

Transact-SQL에는 오류 정보를 가져오는 두 가지 방법이 제공됩니다.

  • TRY...CATCH 구문의 CATCH 블록 범위 내에서 다음 시스템 함수를 사용할 수 있습니다.

    • ERROR_LINE()은 오류가 발생한 줄 번호를 반환합니다.

    • ERROR_MESSAGE()는 응용 프로그램에 반환되는 메시지의 텍스트를 반환합니다. 이 텍스트는 길이, 개체 이름 또는 시간과 같은 대체 가능한 매개 변수에 대해 제공된 값을 포함합니다.

    • ERROR_NUMBER()는 오류 번호를 반환합니다.

    • ERROR_PROCEDURE()는 오류가 발생한 저장 프로시저 또는 트리거의 이름을 반환합니다. 저장 프로시저 또는 트리거 내에서 오류가 발생하지 않은 경우 이 함수는 NULL을 반환합니다.

    • ERROR_SEVERITY()는 심각도를 반환합니다.

    • ERROR_STATE()는 상태를 반환합니다.

  • Transact-SQL 문을 실행한 즉시 오류가 있는지 테스트하고 @@ERROR 함수를 사용하여 오류 번호를 검색할 수 있습니다.

ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY 및 ERROR_STATE 사용

ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY 및 ERROR_STATE 함수는 TRY…CATCH 구문의 CATCH 블록 범위 내에서 사용할 때만 오류 정보를 반환합니다. CATCH 블록의 범위를 벗어나면 NULL을 반환합니다. 이러한 함수는 CATCH 블록을 호출하도록 한 오류에 대한 정보를 반환합니다. 함수는 여러 번 참조되더라도 CATCH 블록의 범위 내에서 실행되는 모든 위치에서 같은 오류 정보를 반환합니다. 함수는 응용 프로그램에 반환되는 것과 같은 데이터를 Transact-SQL 문에 제공합니다.

중첩된 CATCH 블록에서 ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY 및 ERROR_STATE 함수는 해당 함수가 참조되는 CATCH 블록별로 오류 정보를 반환합니다. 예를 들어 외부 TRY...CATCH 구문의 CATCH 블록에 중첩된 TRY...CATCH 구문이 있을 수 있습니다. 중첩된 CATCH 블록 내에서 이러한 함수는 내부 CATCH 블록을 호출한 오류에 대한 정보를 반환합니다. 외부 CATCH 블록에 있는 동일 함수는 해당 CATCH 블록을 호출한 오류에 대한 정보를 반환합니다.

다음 예에서는 ERROR_MESSAGE가 외부 CATCH 블록에서 참조될 때 외부 TRY 블록이 생성한 메시지 텍스트를 반환한다는 것을 보여 줍니다. 내부 CATCH 블록에서 참조될 때 ERROR_MESSAGE는 내부 TRY 블록에 생성된 텍스트를 반환합니다. 다음 예에서는 외부 CATCH 블록에서는 내부 TRY...CATCH 구문이 실행된 후에도 ERROR_MESSAGE가 항상 외부 TRY 블록에 생성된 메시지를 반환한다는 것도 보여 줍니다.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Message text is from the %s TRY block.';
GO
BEGIN TRY -- Outer TRY block.
    -- Raise an error in the outer TRY block.
    RAISERROR (50010, -- Message id.
        16, -- Severity,
        1, -- State,
        N'outer'); -- Indicate TRY block.
END TRY -- Outer TRY block.
BEGIN CATCH -- Outer CATCH block.
    -- Print the error message recieved for this
    -- CATCH block.
    PRINT N'OUTER CATCH1: ' + ERROR_MESSAGE();
    BEGIN TRY -- Inner TRY block.
        -- Start a nested TRY...CATCH and generate
        -- a new error.
        RAISERROR (50010, -- Message id.
            16, -- Severity,
            2, -- State,
            N'inner'); -- Indicate TRY block.
    END TRY -- Inner TRY block.
    BEGIN CATCH -- Inner CATCH block.
        -- Print the error message recieved for this
        -- CATCH block.
        PRINT N'INNER CATCH: ' + ERROR_MESSAGE();
    END CATCH; -- Inner CATCH block.
    -- Show that ERROR_MESSAGE in the outer CATCH
    -- block still returns the message from the
    -- error generated in the outer TRY block.
    PRINT N'OUTER CATCH2: ' + ERROR_MESSAGE();
END CATCH; -- Outer CATCH block.
GO

@@ERROR를 사용하여 정보 검색

@@ERROR 함수를 사용하여 이전 Transact-SQL 문이 생성한 오류 번호를 캡처할 수 있습니다. @@ERROR는 오류를 생성하는 Transact-SQL 문 바로 뒤에서만 오류 정보를 반환합니다.

  • 오류를 생성하는 문이 TRY 블록에 있으면 연결된 CATCH 블록의 첫 번째 문에서 @@ERROR 값을 테스트하고 검색해야 합니다.

  • 오류를 생성하는 문이 TRY 블록에 없으면 오류를 생성하는 문 바로 뒤의 문에서 @@ERROR 값을 테스트하고 검색해야 합니다.

CATCH 블록의 범위를 벗어날 경우 Transact-SQL 코드 내에서 얻을 수 있는 오류 관련 정보는 @@ERROR의 오류 번호뿐입니다. 오류가 sys.messages에 정의된 오류 메시지를 사용한 경우에는 이 예에 나온 대로 sys.messages에서 정의된 심각도와 오류 메시지 텍스트를 검색할 수 있습니다.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
-- Define a message with text that accepts
-- a substitution string.
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Substitution string = %s.';
GO
DECLARE @ErrorVariable INT;
-- RAISERROR uses a different severity and
-- supplies a substitution argument.
RAISERROR (50010, -- Message id.
    15, -- Severity,
    1, -- State,
    N'ABC'); -- Substitution Value.
-- Save @@ERROR.
SET @ErrorVariable = @@ERROR;
-- The results of this select illustrate that
-- outside a CATCH block only the original
-- information from sys.messages is available to
-- Transact-SQL statements. The actual message
-- string returned to the application is not
-- available to Transact-SQL statements outside
-- of a CATCH block.
SELECT @ErrorVariable AS ErrorID,
    text
FROM sys.messages
WHERE message_id = @ErrorVariable;
GO