Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A következőkre vonatkozik:SQL Server
Azure SQL Database
Felügyelt Azure SQL-példány
Azure Synapse Analytics
Elemzési platformrendszer (PDW)
SQL Analytics-végpont a Microsoft Fabricben
Raktár a Microsoft Fabricben
SQL-adatbázis a Microsoft Fabricben
A C# és a Visual C++ nyelv kivételkezeléséhez hasonló Transact-SQL hibakezelését valósítja meg. A blokkokban Transact-SQL utasítások egy csoportja is szerepelhet TRY . Ha hiba történik a blokkban, a TRY vezérlőt általában egy blokkba CATCH zárt utasításcsoportnak továbbítja a rendszer.
Transact-SQL szintaxis konvenciók
Syntax
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Arguments
sql_statement
Bármilyen Transact-SQL utasítás.
statement_block
Egy kötegben vagy blokkban BEGIN...END lévő Transact-SQL utasítások bármely csoportja.
Remarks
A TRY...CATCH szerkezet minden olyan végrehajtási hibát elkap, amely 10-nél nagyobb súlyossággal rendelkezik, és nem zárja be az adatbázis-kapcsolatot.
A TRY blokkokat azonnal egy társított CATCH blokknak kell követnie. Az és az END TRYBEGIN CATCH utasítások közötti egyéb utasítások is szintaxishibát okoznak.
Egy TRY...CATCH szerkezet nem terjedhet ki több kötegre. A TRY...CATCH szerkezetek nem képesek Transact-SQL utasítások több blokkjára. Egy szerkezet például TRY...CATCH nem képes Transact-SQL utasítások két BEGIN...END blokkjára, és nem képes átfogni egy konstrukciót IF...ELSE .
Ha a blokkban TRY található kódban nincsenek hibák, amikor a blokk utolsó utasítása befejeződik, a TRY vezérlő közvetlenül a társított END CATCH utasítás után továbbítja az utasítást.
Ha a blokkba TRY zárt kódban hiba van, a vezérlő a társított CATCH blokk első utasítására kerül. Amikor a blokkban lévő kód befejeződik, a CATCH vezérlő közvetlenül az utasítás után továbbítja az utasítást END CATCH .
Note
Ha az END CATCH utasítás egy tárolt eljárás vagy eseményindító utolsó utasítása, a vezérlő visszakerül a tárolt eljárást meghívó vagy az eseményindítót aktiváló utasításra.
A blokk által CATCH csapdába esett hibák nem lesznek visszaadva a hívó alkalmazásnak. Ha a hibainformációk bármelyik részét vissza kell adni az alkalmazásnak, a CATCH blokk kódjának ezt olyan mechanizmusokkal kell megtennie, mint SELECT például az eredményhalmazok vagy a RAISERROR utasítások PRINT .
TRY...CATCH konstrukciók beágyazhatók. A TRY blokkok vagy blokkok CATCH beágyazott TRY...CATCH szerkezeteket tartalmazhatnak. A blokkok tartalmazhatnak például CATCH beágyazott TRY...CATCH szerkezetet a CATCH kód által észlelt hibák kezelésére.
A blokkokban CATCH előforduló hibákat a rendszer máshol létrehozott hibákként kezeli. Ha a CATCH blokk beágyazott TRY...CATCH szerkezetet tartalmaz, a beágyazott TRY blokk esetleges hibája átadja a vezérlőt a beágyazott CATCH blokknak. Ha nincs beágyazott TRY...CATCH szerkezet, a hiba vissza lesz adva a hívónak.
TRY...CATCH a blokkban TRY lévő kód által végrehajtott tárolt eljárások vagy triggerek nem kezelt hibáit rögzíti. Másik lehetőségként a tárolt eljárások vagy eseményindítók saját TRY...CATCH szerkezeteket is tartalmazhatnak a kódjuk által generált hibák kezelésére. Ha például egy TRY blokk végrehajt egy tárolt eljárást, és hiba történik a tárolt eljárásban, a hiba a következő módokon kezelhető:
Ha a tárolt eljárás nem tartalmazza a saját
TRY...CATCHszerkezetét, a hiba a vezérlőt adja vissza azCATCHutasítást tartalmazóTRYblokkhozEXECUTEtársított blokknak.Ha a tárolt eljárás szerkezetet
TRY...CATCHtartalmaz, a hiba átviszi a vezérlőt aCATCHblokkba a tárolt eljárásban. Amikor aCATCHblokkkód befejeződik, a rendszer a vezérlőt közvetlenül a tárolt eljárást meghívó utasítás után adja vissza azEXECUTEutasításnak.
GOTOutasításokkal nem lehet beírni egy vagy TRY több blokkotCATCH.
GOTO utasításokkal egy címkére ugorhat ugyanazon TRY vagy CATCH blokkon belül, vagy elhagyhat egy TRY vagy CATCH több blokkot.
A TRY...CATCH szerkezet nem használható felhasználó által definiált függvényekben.
Hibainformációk lekérése
A blokk hatókörében CATCH a következő rendszerfüggvények használhatók a blokk végrehajtását okozó CATCH hibával kapcsolatos információk lekérésére:
| Function | Description |
|---|---|
| ERROR_NUMBER | A hiba számát adja eredményül. |
| ERROR_SEVERITY | A súlyosságot adja vissza. |
| ERROR_STATE | A hibaállapot számát adja eredményül. |
| ERROR_PROCEDURE | Annak a tárolt eljárásnak vagy eseményindítónak a nevét adja vissza, ahol a hiba történt. |
| ERROR_LINE | A hibát okozó rutinon belüli sorszámot adja vissza. |
| ERROR_MESSAGE | A hibaüzenet teljes szövegét adja vissza. A szöveg tartalmazza a helyettesíthető paraméterekhez megadott értékeket, például a hosszokat, az objektumneveket vagy az időpontokat. |
Ezek a függvények akkor térnek vissza NULL , ha a blokk hatókörén CATCH kívül vannak meghívva. A hibainformációk a blokk hatókörének CATCH bármely pontjáról lekérhetők ezen függvények használatával. Az alábbi szkript például egy tárolt eljárást mutat be, amely hibakezelési függvényeket tartalmaz.
CATCH A szerkezet blokkjában TRY...CATCH a rendszer meghívja a tárolt eljárást, és visszaadja a hibával kapcsolatos információkat.
-- 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;
A ERROR_* függvények egy CATCHnatívan lefordított tárolt eljárás blokkjában is működnek.
A TRY által nem észlelt hibák... CATCH szerkezet
TRY...CATCH a szerkezetek nem csapják le a következő feltételeket:
10 vagy annál kisebb súlyosságú figyelmeztetések vagy tájékoztató üzenetek.
20 vagy annál nagyobb súlyosságú hibák, amelyek leállják az SQL Server adatbázismotorjának feladatfeldolgozását a munkamenethez. Ha olyan hiba történik, amely 20 vagy annál nagyobb súlyossággal rendelkezik, és az adatbázis-kapcsolat nem szakad meg,
TRY...CATCHkezeli a hibát.Figyelemfelhívások, például ügyfél-megszakítási kérések vagy megszakadt ügyfélkapcsolatok.
Amikor egy rendszergazda az
KILLutasítást használja a munkamenet befejezéséhez.
A következő típusú hibákat a blokkok nem kezelik CATCH , ha azok a szerkezettel azonos végrehajtási TRY...CATCH szinten fordulnak elő:
Fordítási hibák, például szintaxishibák, amelyek megakadályozzák a köteg futását.
Az utasításszintű újrafordítás során fellépő hibák, például az objektumok névfeloldási hibái, amelyek a halasztott névfeloldás miatt a fordítás után következnek be.
Objektumnévfeloldási hibák
Ezek a hibák a köteg, a tárolt eljárás vagy az eseményindító futtatásának szintjére kerülnek vissza.
Ha a fordítás vagy az utasításszintű újrafordítás során hiba történik alacsonyabb végrehajtási szinten (például végrehajtáskor sp_executesql vagy felhasználó által definiált tárolt eljárás esetén), TRY a hiba a szerkezetnél TRY...CATCH alacsonyabb szinten jelentkezik, és a társított CATCH blokk fogja kezelni.
Az alábbi példa bemutatja, hogy egy SELECT utasítás által generált objektumnévfeloldási hibát nem a szerkezet észleli TRY...CATCH , hanem a CATCH blokk észleli, amikor ugyanazt SELECT az utasítást egy tárolt eljárásban hajtja végre.
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
A hiba nem jelenik meg, és a TRY...CATCH vezérlés a következő magasabb szintre kerül.
Ha egy tárolt eljárásban futtatja az SELECT utasítást, a hiba a blokknál TRY alacsonyabb szinten jelentkezik. A hibát a TRY...CATCH szerkezet kezeli.
-- 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;
Nem véglegesíthető tranzakciók és XACT_STATE
Ha egy TRY blokkban generált hiba az aktuális tranzakció állapotát érvényteleníti, a tranzakció nem véglegesített tranzakcióként lesz besorolva. Egy olyan hiba, amely általában egy blokkon kívüli TRY tranzakciót végződik, a tranzakció nem egyeztethető állapotba kerül, amikor a hiba egy TRY blokkon belül történik. A nem véglegesített tranzakciók csak olvasási műveleteket vagy egy ROLLBACK TRANSACTION. A tranzakció nem tud olyan Transact-SQL utasítást végrehajtani, amely írási műveletet vagy COMMIT TRANSACTIONegy . A XACT_STATE függvény annak értékét -1 adja vissza, ha egy tranzakciót nem véglegesített tranzakcióként soroltak be. Amikor egy köteg befejeződik, az adatbázismotor visszaállítja az aktív, nem véglegesíthető tranzakciókat. Ha a tranzakció nem véglegesített állapotba helyezésekor nem érkezett hibaüzenet, a köteg befejeződésekor a rendszer hibaüzenetet küld az ügyfélalkalmazásnak. Ez azt jelzi, hogy a rendszer nem véglegesített tranzakciót észlelt és visszaállított.
További információ a nem véglegesíthető tranzakciókról és a XACT_STATE függvényről: XACT_STATE.
Examples
A. A TRY használata... ELKAP
Az alábbi példa egy olyan utasítást SELECT mutat be, amely osztva nullával hibát okoz. A hiba miatt a végrehajtás a társított CATCH blokkra ugrik.
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. A TRY használata... CATCH egy tranzakcióban
Az alábbi példa bemutatja, hogyan működik egy TRY...CATCH blokk egy tranzakción belül. A blokkon belüli TRY utasítás kényszermegsértési hibát okoz.
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. A TRY használata... CATCH és XACT_STATE
Az alábbi példa bemutatja, hogyan kezelhetők a tranzakción belül előforduló hibák a TRY...CATCH szerkezettel. A XACT_STATE függvény meghatározza, hogy a tranzakciót le kell-e véglegesíteni vagy vissza kell-e állítani. Ebben a példában SET XACT_ABORT a következő: ON. Így a tranzakció nem lesz véglegesíthető, ha a korlátozásmegsértési hiba bekövetkezik.
-- 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
Kapcsolódó tartalom
- DOBÁS (Transact-SQL)
- Adatbázismotor hiba súlyosságai
- ERROR_LINE (Transact-SQL)
- ERROR_MESSAGE (Transact-SQL)
- ERROR_NUMBER (Transact-SQL)
- ERROR_PROCEDURE (Transact-SQL)
- ERROR_SEVERITY (Transact-SQL)
- ERROR_STATE (Transact-SQL)
- RAISERROR (Transact-SQL)
- @@ERROR (Transact-SQL)
- GOTO (Transact-SQL)
- KEZDŐDIK... VÉGE (Transact-SQL)
- XACT_STATE (Transact-SQL)
- SET XACT_ABORT (Transact-SQL)