... TRY CATCH (języka Transact-SQL)

Błąd narzędzi obsługi Transact-SQL który jest podobny do obsługi w wyjątków Microsoft Program Visual C# i Microsoft Języki Visual C++. Grupy Transact-SQL instrukcje mogą być ujęte w blok TRY. W przypadku wystąpienia błędu w blok TRY, kontrola jest przekazywana do innej grupy instrukcji, ujęty w blok CATCH.

Topic link iconKonwencje składni języka Transact-SQL

BEGIN TRY
     { sql_statement | statement_block }
END TRY
BEGIN CATCH
          [ { sql_statement | statement_block } ]
END CATCH
[ ; ]

Argumenty

  • sql_statement
    Jest dowolną Transact-SQL Instrukcja.

  • statement_block
    Każda grupa Transact-SQL instrukcje w serii lub w blok BEGIN…END.

Remarks

Konstrukcja TRY…CATCH połowy wszystkie błędy wykonania, których ważności wyższym niż 10, która nie należy zamykać połączenia bazy danych.

Blok TRY musi następować bezpośrednio przez skojarzony blokiem CATCH.W tym inne instrukcje między END TRY i instrukcji BEGIN CATCH generuje błąd składni.

Konstrukcja TRY…CATCH nie może obejmować wiele instancji.Konstrukcja TRY…CATCH nie może obejmować wiele bloków Transact-SQL instrukcje. Na przykład konstrukcji TRY…CATCH nie może obejmować dwa bloki BEGIN…END Transact-SQL instrukcje i nie może obejmować konstrukcja IF…ELSE.

Jeśli nie wystąpią błędy w kodzie ujęty w blok TRY, po zakończeniu ostatniego wyciągu w blok TRY, formant przekazuje do instrukcja znajdującej się bezpośrednio po skojarzone instrukcja END CATCH.Jeśli występuje błąd w kodzie ujęty w blok TRY, kontrolować przechodzi do pierwszej instrukcja w skojarzonym blok CATCH.Jeśli instrukcja END CATCH jest ostatniej instrukcji w procedurze przechowywanej lub wyzwalacza, kontrola jest przekazywana do instrukcji, która o nazwie procedura przechowywana lub uruchomienia wyzwalacza.

Jeśli kod w połowy blok kończy formant przechodzi do instrukcja znajdującej się bezpośrednio po instrukcja END CATCH.Błędy stosowane nadlewki i podlewki w blok CATCH nie są zwracane do aplikacji wywołującej.Jeśli jakakolwiek część informacji o błędach muszą zostać zwrócone do aplikacji, kod w blok CATCH muszą to robić przy użyciu mechanizmów, takich jak zestawy wyników SELECT lub instrukcji RAISERROR i PRINT.Aby uzyskać więcej informacji na temat korzystania z TRY…CATCH RAISERROR zobacz Za pomocą TRY... CATCH instrukcji języka Transact-SQL.

Konstrukcje TRY…CATCH mogą być zagnieżdżane.Blok TRY lub bloku CATCH może zawierać zagnieżdżonego konstrukcje TRY…CATCH.Na przykład blok CATCH może zawierać osadzony konstrukcja TRY…CATCH do obsługi błędów napotkanych przez kod CATCH.

Błędy w blok CATCH są traktowane tak, jak błędy wygenerowane w dowolnym innym miejscu.Jeśli bloku CATCH zawiera zagnieżdżone konstrukcja TRY…CATCH, każdy błąd w zagnieżdżony blok TRY przechodziła formantu zagnieżdżonych bloku CATCH.Jeśli nie ma żadnych zagnieżdżonych konstrukcja TRY…CATCH, błędu jest przekazywany do obiektu wywołującego.

Konstrukcje TRY…CATCH catch nieobsługiwany błędy z procedur przechowywanych i wyzwalaczy wykonywane przez kod w blok TRY.Można także procedury przechowywane i wyzwalacze mogą zawierać własne konstrukcje TRY…CATCH do obsługi błędów generowanych przez ich kodu.Na przykład gdy blok TRY wykonuje procedura przechowywana i występuje błąd w procedurze przechowywanej, błąd można obsługiwać w następujący sposób:

  • Jeśli procedura przechowywana nie zawiera swoją własną konstrukcja TRY…CATCH, błąd przekazuje sterowanie do blok CATCH skojarzone z blok TRY zawierający instrukcja wykonać.

  • Jeśli procedura przechowywana zawiera konstrukcja TRY…CATCH, błąd przekazuje sterowanie do połowy blok w procedurze przechowywanej.Po zakończeniu wykonywania kodu blok CATCH, kontrola jest przekazywana do instrukcja znajdującej się bezpośrednio po instrukcja wykonać, który wywołał procedura przechowywana.

Instrukcje GOTO nie można używać do wprowadzania blok TRY lub CATCH.Instrukcje GOTO można użyć do wykonania skoku do etykiety, w tym samym blok TRY lub CATCH lub pozostawić blok TRY lub CATCH.

Konstrukcja TRY…CATCH nie mogą być używane w przypadku funkcja zdefiniowanej przez użytkownika.

Pobiera informacje o błędach

W zakres blok CATCH, następujące funkcje systemowe mogą być używane do wyświetlania informacji na temat błędu, który spowodował blok CATCH do wykonania:

  • ERROR_NUMBER() zwraca numer błędu.

  • ERROR_SEVERITY() zwraca wagę.

  • ERROR_STATE() zwraca numer stanu błędu.

  • ERROR_PROCEDURE() zwraca nazwę procedura przechowywana lub wyzwalacza, w którym wystąpił błąd.

  • ERROR_LINE() zwraca numer wiersza wewnątrz procedury, która spowodowała błąd.

  • ERROR_MESSAGE() zwraca pełny tekst komunikatu o błędzie.Tekst zawiera wartości dostarczone parametrów wymiennych, takich jak długości nazw obiektów i godziny.

Funkcje zwracają wartość NULL, jeśli są one nazywane poza zakres blok CATCH.Informacje o błędzie może być pobrany przy użyciu funkcji z dowolnego miejsca w zakresie blok CATCH.Na przykład poniższy skrypt zawiera procedura przechowywana, która zawiera funkcje obsługi błędów.W CATCH blok z TRY…CATCH konstrukcja, procedura przechowywana jest wywoływana i informacji na temat błędu jest zwracany.

USE AdventureWorks;
GO
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL 
    DROP PROCEDURE usp_GetErrorInfo;
GO

-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
    ERROR_NUMBER() AS ErrorNumber
    ,ERROR_SEVERITY() AS ErrorSeverity
    ,ERROR_STATE() AS ErrorState
    ,ERROR_PROCEDURE() AS ErrorProcedure
    ,ERROR_LINE() AS ErrorLine
    ,ERROR_MESSAGE() AS ErrorMessage;
GO

BEGIN TRY
    -- Generate divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    -- Execute error retrieval routine.
    EXECUTE usp_GetErrorInfo;
END CATCH;

Błędy, które nie mają wpływu budowanie TRY…CATCH

Konstrukcje TRY…CATCH nie stosowane następujące warunki:

  • Ostrzeżenia lub komunikaty informacyjne, których wskaźnik ważności dla 10 lub niższym.

  • Błędy, które ma wskaźnik ważności dla 20 lub większa tego stop SQL Server Database Engine zadania przetwarzania dla sesja. Jeśli wystąpi błąd, który ma wskaźnik ważności 20 lub większa, a połączenie z bazą danych nie jest zakłócony, TRY…CATCH będzie obsługi błędu.

  • Attentions, takich jak żądania przerwań klient lub klient zerwane połączenia.

  • Gdy sesja jest zakończona przez administrator systemu przy użyciu instrukcja "zabicia".

Następujące typy błędów nie są obsługiwane przez blok CATCH, kiedy występują one w tym samym poziom wykonania jako konstrukcja TRY…CATCH:

  • Skompiluj błędów, takich jak błędy składni, uniemożliwiające uruchomienie partia.

  • Błędy, które występują podczas ponownej kompilacji instrukcja poziom, takich jak błędów rozpoznawania nazw obiektu występujące po kompilacji z powodu rozpoznawania nazw odroczone.

Te błędy są zwracane do poziom który uruchomił partia, procedura przechowywana lub wyzwalacza.

W przypadku wystąpienia błędu podczas kompilacji lub ponownej kompilacji poziomie instrukcja na niższym poziomie wykonywania (na przykład, podczas wykonywania sp_executesql lub użytkownika przez procedura przechowywana) wewnątrz blok TRY błąd pojawia się na niższym poziomie niż konstrukcji TRY…CATCH i będzie obsługiwany przez skojarzony blok CATCH.Aby uzyskać więcej informacji zobaczZa pomocą TRY... CATCH instrukcji języka Transact-SQL.

W poniższym przykładzie pokazano, jak obiekt błąd rozpoznawania nazwy generowane przez SELECT Instrukcja nie jest objęte TRY…CATCH Konstruowanie, ale jest objęte CATCH blokowanie, kiedy takie same SELECT Instrukcja jest wykonywane wewnątrz procedura przechowywana.

USE AdventureWorks;
GO

BEGIN TRY
    -- Table does not exist; object name resolution
    -- error not caught.
    SELECT * FROM NonexistentTable;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH

Błąd nie wpadł i kontrolować przechodzi z TRY…CATCH Konstruowanie następny wyższy poziom.

Uruchamianie SELECT Instrukcja wewnątrz procedura przechowywana spowoduje błąd występuje poziom niższym niż TRY blok. Ten błąd będzie obsługiwany przez TRY…CATCH konstrukcja.

-- Verify that the stored procedure does not exist.
IF OBJECT_ID ( N'usp_ExampleProc', N'P' ) IS NOT NULL 
    DROP PROCEDURE usp_ExampleProc;
GO

-- Create a stored procedure that will cause an 
-- object resolution error.
CREATE PROCEDURE usp_ExampleProc
AS
    SELECT * FROM NonexistentTable;
GO

BEGIN TRY
    EXECUTE usp_ExampleProc;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
  • Aby uzyskać więcej informacji na temat partii zobacz Batches.

niemożliwy do zatwierdzenia transakcje i XACT_STATE

Jeśli błąd generowane w blok TRY powoduje, że stan bieżących transakcji, która ma być unieważnione, transakcja jest klasyfikowany jako transakcja niemożliwy do zatwierdzenia.Błąd, który zazwyczaj kończy się transakcji poza blok TRY powoduje, że transakcja do wprowadzania niemożliwy do zatwierdzenia stan, gdy wystąpi błąd wewnątrz blok TRY.Transakcja niemożliwy do zatwierdzenia tylko mogą wykonywać operacje odczytu i transakcji ROLLBACK.Transakcja nie może wykonać dowolny Transact-SQL instrukcje, które będą generować operacji zapisu lub transakcji zatwierdzanie. Funkcja XACT_STATE zwraca wartość -1, jeśli transakcja został sklasyfikowany jako transakcja niemożliwy do zatwierdzenia.Po zakończeniu pracy z serii Database Engine powoduje powrót wszystkich aktywnych transakcji niemożliwy do zatwierdzenia. Jeśli żaden komunikat o błędzie nie została wysłana, gdy wprowadzona niemożliwy do zatwierdzenia stan transakcji po zakończeniu pracy partia, do aplikacji klienckiej wysyłany jest komunikat o błędzie.Oznacza to, że transakcja niemożliwy do zatwierdzenia został wykryty i wycofana.

Aby uzyskać więcej informacji na temat transakcji niemożliwy do zatwierdzenia i funkcja XACT_STATE zobacz Za pomocą TRY... CATCH instrukcji języka Transact-SQL i XACT_STATE (Transact-SQL).

Przykłady

A.Za pomocą TRY…CATCH

W poniższym przykładzie SELECT instrukcja generuje błąd dzielenia przez zero. Błąd powoduje, że wykonanie przejść do skojarzonym CATCH blok.

USE AdventureWorks;
GO

BEGIN TRY
    -- Generate a divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    SELECT
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO

B.Za pomocą TRY…CATCH w transakcji

W poniższym przykładzie w jaki sposób TRY…CATCH blokowanie działa wewnątrz transakcji. Instrukcja wewnątrz TRY Blok generuje błąd naruszenia ograniczeń.

USE AdventureWorks;
GO
BEGIN TRANSACTION;

BEGIN TRY
    -- Generate a constraint violation error.
    DELETE FROM Production.Product
    WHERE ProductID = 980;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

C.Przy użyciu XACT_STATE TRY…CATCH

W poniższym przykładzie przedstawiono sposób użycia TRY…CATCH Konstruowanie do obsługi błędów występujących wewnątrz transakcji. The XACT_STATE funkcja determines whether the transaction should be committed or rolled back. W tym przykładzie SET XACT_ABORT jest ON. Dzięki temu transakcji niemożliwy do zatwierdzenia po wystąpieniu błędu naruszenie ograniczenia.

USE AdventureWorks;
GO

-- Check to see whether this stored procedure exists.
IF OBJECT_ID (N'usp_GetErrorInfo', N'P') IS NOT NULL
    DROP PROCEDURE usp_GetErrorInfo;
GO

-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_LINE () AS ErrorLine
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_MESSAGE() AS ErrorMessage;
GO

-- SET XACT_ABORT ON will cause the transaction to be uncommittable
-- when the constraint violation occurs. 
SET XACT_ABORT ON;

BEGIN TRY
    BEGIN TRANSACTION;
        -- A FOREIGN KEY constraint exists on this table. This 
        -- statement will generate a constraint violation error.
        DELETE FROM Production.Product
            WHERE ProductID = 980;

    -- If the DELETE statement succeeds, commit the transaction.
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- Execute error retrieval routine.
    EXECUTE usp_GetErrorInfo;

    -- Test XACT_STATE:
        -- If 1, the transaction is committable.
        -- If -1, the transaction is uncommittable and should 
        --     be rolled back.
        -- XACT_STATE = 0 means that there is no transaction and
        --     a commit or rollback operation would generate an error.

    -- Test whether the transaction is uncommittable.
    IF (XACT_STATE()) = -1
    BEGIN
        PRINT
            N'The transaction is in an uncommittable state.' +
            'Rolling back transaction.'
        ROLLBACK TRANSACTION;
    END;

    -- Test whether the transaction is committable.
    IF (XACT_STATE()) = 1
    BEGIN
        PRINT
            N'The transaction is committable.' +
            'Committing transaction.'
        COMMIT TRANSACTION;   
    END;
END CATCH;
GO