Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Punkt końcowy analizy SQL w usłudze Microsoft Fabric
Hurtownia danych w usłudze Microsoft Fabric
Baza danych SQL w usłudze Microsoft Fabric
Implementuje obsługę błędów dla Transact-SQL, które są podobne do obsługi wyjątków w językach C# i Visual C++. Grupę instrukcji Transact-SQL można ujęć w TRY blok. Jeśli w TRY bloku wystąpi błąd, kontrolka jest zwykle przekazywana do innej grupy instrukcji, które są ujęte w CATCH bloku.
Transact-SQL konwencje składni
Syntax
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Arguments
sql_statement
Dowolna instrukcja Transact-SQL.
statement_block
Każda grupa instrukcji Transact-SQL w partii lub ujęta w BEGIN...END blok.
Remarks
Konstrukcja TRY...CATCH przechwytuje wszystkie błędy wykonywania o ważności większej niż 10, które nie zamykają połączenia z bazą danych.
Blok TRY musi być natychmiast obserwowany przez skojarzony CATCH blok. Dołączenie innych instrukcji między instrukcjami END TRY i BEGIN CATCH powoduje wygenerowanie błędu składniowego.
Konstrukcja TRY...CATCH nie może obejmować wielu partii. Konstrukcja TRY...CATCH nie może obejmować wielu bloków instrukcji Transact-SQL. Na przykład TRY...CATCH konstrukcja nie może obejmować dwóch BEGIN...END bloków instrukcji Transact-SQL i nie może obejmować IF...ELSE konstrukcji.
Jeśli w kodzie, który znajduje się w TRY bloku, nie ma żadnych błędów, po zakończeniu TRY ostatniej instrukcji w bloku kontrolka przechodzi do instrukcji bezpośrednio po skojarzonej END CATCH instrukcji.
Jeśli w kodzie, który znajduje się w TRY bloku, występuje błąd, kontrolka przechodzi do pierwszej instrukcji w skojarzonym CATCH bloku. Po zakończeniu CATCH kodu w bloku kontrolka przechodzi do instrukcji bezpośrednio po instrukcji END CATCH .
Note
END CATCH Jeśli instrukcja jest ostatnią instrukcją w procedurze składowanej lub wyzwalaczu, kontrolka jest przekazywana z powrotem do instrukcji, która wywołała procedurę składowaną lub wyzwoliła wyzwalacz.
Błędy uwięzione przez CATCH blok nie są zwracane do aplikacji wywołującej. Jeśli jakakolwiek część informacji o błędzie musi zostać zwrócona do aplikacji, kod w CATCH bloku musi to zrobić przy użyciu mechanizmów, takich jak SELECT zestawy wyników lub RAISERROR instrukcje i PRINT .
TRY...CATCH konstrukcje można zagnieżdżać.
TRY Blok lub CATCH blok może zawierać konstrukcje zagnieżdżoneTRY...CATCH. Na przykład CATCH blok może zawierać konstrukcję osadzoną TRY...CATCH do obsługi błędów napotkanych przez CATCH kod.
Błędy napotkane w bloku są traktowane jak błędy generowane w CATCH dowolnym miejscu.
CATCH Jeśli blok zawiera konstrukcję zagnieżdżonąTRY...CATCH, każdy błąd w zagnieżdżonym TRY bloku przekazuje kontrolę do zagnieżdżonego CATCH bloku. Jeśli nie ma konstrukcji zagnieżdżonej TRY...CATCH , błąd zostanie przekazany z powrotem do elementu wywołującego.
TRY...CATCH konstrukcje przechwytują nieobsługiwane błędy z procedur składowanych lub wyzwalaczy wykonywanych przez kod w TRY bloku. Alternatywnie procedury składowane lub wyzwalacze mogą zawierać własne TRY...CATCH konstrukcje do obsługi błędów generowanych przez ich kod. Na przykład gdy TRY blok wykonuje procedurę składowaną i występuje błąd w procedurze składowanej, błąd można obsłużyć w następujący sposób:
Jeśli procedura składowana nie zawiera własnej
TRY...CATCHkonstrukcji, błąd zwraca kontrolkę doCATCHbloku skojarzonegoTRYz blokiem zawierającym instrukcjęEXECUTE.Jeśli procedura składowana zawiera konstrukcję
TRY...CATCH, błąd przenosi kontrolkę doCATCHbloku w procedurze składowanej. Po zakończeniu kodu bloku kontrolkaCATCHjest przekazywana z powrotem do instrukcji bezpośrednio poEXECUTEinstrukcji, która nazwała procedurę składowaną.
GOTO instrukcji nie można używać do wprowadzania instrukcji TRY lub CATCH .
GOTO instrukcje mogą służyć do przechodzenia do etykiety wewnątrz tego samego TRY lub CATCH bloku lub do pozostawienia TRY lub CATCH bloku.
Konstrukcji TRY...CATCH nie można używać w funkcji zdefiniowanej przez użytkownika.
Pobieranie informacji o błędzie
W zakresie CATCH bloku następujące funkcje systemowe mogą służyć do uzyskiwania informacji o błędzie, który spowodował CATCH wykonanie bloku:
| Function | Description |
|---|---|
| ERROR_NUMBER | Zwraca liczbę błędu. |
| ERROR_SEVERITY | Zwraca ważność. |
| ERROR_STATE | Zwraca numer stanu błędu. |
| ERROR_PROCEDURE | Zwraca nazwę procedury składowanej 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 podane dla wszystkich parametrów podstawialnych, takich jak długość, nazwy obiektów lub godziny. |
Te funkcje są zwracane NULL , jeśli są wywoływane poza zakresem CATCH bloku. Informacje o błędzie można pobrać przy użyciu tych funkcji z dowolnego miejsca w zakresie CATCH bloku. Na przykład poniższy skrypt przedstawia procedurę składowaną zawierającą funkcje obsługi błędów.
CATCH W bloku TRY...CATCH konstrukcji wywoływana jest procedura składowana i zwracane są informacje o błędzie.
-- 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;
Funkcje ERROR_* działają również w CATCH bloku wewnątrz natywnie skompilowanej procedury składowanej.
Błędy, których nie dotyczy próba... Catch
TRY...CATCH konstrukcje nie wychwytują następujących warunków:
Ostrzeżenia lub komunikaty informacyjne, które mają ważność 10 lub niższą.
Błędy o ważności 20 lub wyższej, które zatrzymują przetwarzanie zadania aparatu bazy danych programu SQL Server dla sesji. Jeśli wystąpi błąd o ważności 20 lub wyższej, a połączenie z bazą danych nie zostanie przerwane,
TRY...CATCHobsłuży błąd.Uwagi, takie jak żądania przerwania klienta lub przerwane połączenia klienta.
Gdy administrator systemu używa instrukcji
KILL, aby zakończyć sesję.
Następujące typy błędów nie są obsługiwane przez CATCH blok, gdy występują na tym samym poziomie wykonywania co TRY...CATCH konstrukcja:
Skompiluj błędy, takie jak błędy składni, które uniemożliwiają uruchomienie partii.
Błędy występujące podczas ponownej kompilacji na poziomie instrukcji, takie jak błędy rozpoznawania nazw obiektów występujące po kompilacji z powodu odroczonego rozpoznawania nazw.
Błędy rozpoznawania nazw obiektów
Te błędy są zwracane do poziomu, na poziomie, na który uruchomiono partię, procedurę składowaną lub wyzwalacz.
Jeśli podczas kompilacji lub ponownej kompilacji na poziomie instrukcji wystąpi błąd na niższym poziomie wykonywania (na przykład podczas wykonywania sp_executesql lub procedury składowanej zdefiniowanej przez użytkownika) wewnątrz TRY bloku, błąd występuje na niższym poziomie niż TRY...CATCH konstrukcja i będzie obsługiwany przez skojarzony CATCH blok.
W poniższym przykładzie pokazano, jak błąd rozpoznawania nazw obiektów generowany przez instrukcję SELECT nie jest przechwytywane przez TRY...CATCH konstrukcję, ale jest przechwycony przez CATCH blok, gdy ta sama SELECT instrukcja jest wykonywana wewnątrz procedury składowanej.
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 jest przechwycony, a kontrola przechodzi z TRY...CATCH konstrukcji do następnego wyższego poziomu.
Uruchomienie instrukcji SELECT wewnątrz procedury składowanej powoduje wystąpienie błędu na poziomie niższym niż TRY blok. Błąd jest obsługiwany przez konstrukcję TRY...CATCH .
-- 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;
Niezatwierdzonych transakcji i XACT_STATE
Jeśli błąd wygenerowany w TRY bloku powoduje unieważnienie stanu bieżącej transakcji, transakcja jest klasyfikowana jako transakcja nietwierdzona. Błąd, który zwykle kończy transakcję poza blokiem TRY , powoduje, że transakcja wprowadza stan niezatwierdzony, gdy błąd występuje wewnątrz TRY bloku. Transakcja nieutwierdzonych może wykonywać tylko operacje odczytu lub ROLLBACK TRANSACTION. Transakcja nie może wykonać żadnych instrukcji Transact-SQL, które generują operację zapisu lub COMMIT TRANSACTION. Funkcja XACT_STATE zwraca wartość -1 , jeśli transakcja została sklasyfikowana jako transakcja nieupowierzytna. Po zakończeniu wsadu aparat bazy danych wycofa wszystkie aktywne niezatwierdzonych transakcji. Jeśli żaden komunikat o błędzie nie został wysłany, gdy transakcja została wprowadzona w stanie niezatwierdzonych, po zakończeniu wsadu do aplikacji klienckiej zostanie wysłany komunikat o błędzie. Oznacza to, że wykryto niezatwierdzonej transakcji i wycofano.
Aby uzyskać więcej informacji na temat niezatwierdzonych transakcji i XACT_STATE funkcji, zobacz XACT_STATE.
Examples
A. Użyj funkcji TRY... ŁAPAĆ
W poniższym przykładzie pokazano instrukcję SELECT , która generuje błąd dzielenia przez zero. Błąd powoduje przejście wykonywania do skojarzonego CATCH bloku.
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. Użyj funkcji TRY... CATCH w transakcji
W poniższym przykładzie pokazano, jak TRY...CATCH blok działa wewnątrz transakcji. Instrukcja wewnątrz TRY bloku generuje błąd naruszenia ograniczeń.
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. Użyj funkcji TRY... CATCH z XACT_STATE
W poniższym przykładzie pokazano, jak za pomocą TRY...CATCH konstrukcji obsługiwać błędy występujące wewnątrz transakcji. Funkcja XACT_STATE określa, czy transakcja powinna zostać zatwierdzona, czy wycofana. W tym przykładzie SET XACT_ABORT jest ON. Powoduje to, że transakcja nie jest zatwierdzana, gdy wystąpi błąd naruszenia ograniczenia.
-- 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.
-- You may want to commit a transaction in a catch block if you want to commit changes to statements that ran prior to the error.
IF (XACT_STATE()) = 1
BEGIN
PRINT N'The transaction is committable. Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH;
GO
Treści powiązane
- RZUĆ (Transact-SQL)
- Ważność błędów aparatu bazy danych
- ERROR_LINE (Transact-SQL)
- ERROR_MESSAGE (Transact-SQL)
- ERROR_NUMBER (Transact-SQL)
- BŁĄD_PROCEDURY (Transact-SQL)
- ERROR_SEVERITY (Transact-SQL)
- ERROR_STATE (Transact-SQL)
- RAISERROR (Transact-SQL)
- @@ERROR (Transact-SQL)
- GOTO (Transact-SQL)
- ZACZYNAĆ... KONIEC (Transact-SQL)
- XACT_STATE (Transact-SQL)
- USTAW XACT_ABORT (Transact-SQL)