T-SQL-hibakezelés implementálása
A hiba egy adatbázisművelet során felmerülő problémát vagy jelentős problémát jelez. Az SQL Server adatbázismotorja rendszerszintű eseményre vagy hibára válaszul hibákat generálhat; vagy alkalmazáshibákat hozhat létre a Transact-SQL kódban.
Az adatbázismotor hibáinak elemei
Bármi legyen is az ok, minden hiba a következő elemekből áll:
- Hibaszám – Az adott hibát azonosító egyedi szám.
- Hibaüzenet – A hibát leíró szöveg.
- Súlyosság – 1 és 25 közötti súlyosság numerikus jelzése.
- Állapot – Az adatbázismotor feltételének belső állapotkódja.
- Eljárás – Annak a tárolt eljárásnak vagy eseményindítónak a neve, amelyben a hiba történt.
- Sorszám – A batch vagy eljárás melyik utasítása generálta a hibát.
Rendszerhibák
A rendszerhibák előre definiálva vannak, és a sys.messages rendszernézetben tekintheti meg őket. Rendszerhiba esetén az SQL Server automatikus szervizelési műveletet hajthat végre a hiba súlyosságától függően. Ha például nagy súlyosságú hiba történik, az SQL Server offline állapotba hozhat egy adatbázist, vagy akár le is állíthatja az adatbázismotor-szolgáltatást.
Egyéni hibák
A Transact-SQL kódban hibákat generálhat az alkalmazásspecifikus feltételekre való reagáláshoz, vagy testre szabhatja az ügyfélalkalmazásoknak rendszerhibákra válaszul küldött információkat. Ezek az alkalmazáshibák definiálhatók beágyazottan a létrehozásuk helyén, vagy előre definiálhatók a sys.messages táblában a rendszer által megadott hibák mellett. Az egyéni hibákhoz használt hibaszámoknak 50001 vagy újabbnak kell lenniük.
Ha egyéni hibaüzenetet szeretne hozzáadni a sys.messages szolgáltatáshoz, használja a sp_addmessage. Az üzenet felhasználójának a sysadmin vagy a serveradmin rögzített kiszolgálói szerepkörök tagjának kell lennie.
A következő az sp_addmessage szintaxis:
sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg'
[ , [ @lang= ] 'language' ]
[ , [ @with_log= ] { 'TRUE' | 'FALSE' } ]
[ , [ @replace= ] 'replace' ]
Íme egy példa az alábbi szintaxist használó egyéni hibaüzenetre:
sp_addmessage 50001, 10, N’Unexpected value entered’;
Emellett egyéni hibaüzeneteket is definiálhat, a sysadmin kiszolgálói szerepkör tagjai egy további paramétert is használhatnak, @with_log. Ha IGAZ értékre van állítva, a hiba a Windows-alkalmazásnaplóban is rögzítésre kerül. A Windows-alkalmazásnaplóba írt üzenetek az SQL Server hibanaplójába is bekerülnek. Érdemes megfontolni a @with_log opció használatát, mivel a hálózati és rendszergazdák általában nem kedvelik a rendszernaplókban csevegősnek számító alkalmazásokat. Ha azonban a hibát riasztásnak kell észlelnie, először a hibát a Windows alkalmazásnaplóba kell írni.
Megjegyzés:
A rendszerhibák jelentése nem támogatott.
Az üzeneteket a @replace = "replace" lehetőséggel lehet helyettesíteni anélkül, hogy először törölnék őket.
Az üzenetek testre szabhatók, és különbözőeket adhat hozzá ugyanahhoz a hibaszámhoz több nyelv esetében, language_id érték alapján.
Megjegyzés:
Az angol nyelvű üzenetek nyelvi azonosítója: 1033.
Hibák generálása a RAISERROR használatával
A PRINT és a RAISERROR is használható információk vagy figyelmeztető üzenetek alkalmazásoknak való visszaadására. A RAISERROR lehetővé teszi az alkalmazások számára, hogy olyan hibát okozzanak, amelyet a hívási folyamat észlelhet.
RAISERROR
A T-SQL-ben való hibaemelés lehetősége megkönnyíti a hibakezelést az alkalmazásban, mivel úgy van elküldve, mint bármely más rendszerhiba. A RAISERROR a következőre használható:
- Segítség a T-SQL-kód hibaelhárításához.
- Ellenőrizze az adatok értékeit.
- Változó szöveget tartalmazó üzeneteket ad vissza.
Megjegyzés:
A PRINT parancs használata hasonló a 10-es szintű hiba kiváltásához.
Íme egy példa egy egyéni hibaüzenetre a RAISERROR használatával.
RAISERROR (N'%s %d', -- Message text,
10, -- Severity,
1, -- State,
N'Custom error message number',
2)
Amikor aktiválódik, a következőt adja vissza:
Custom error message number 2
Az előző példában a%d egy szám helyőrzője, %s pedig egy sztring helyőrzője. Emellett vegye figyelembe, hogy nem említettek meg egy üzenetszámot. Ha az üzenetsztringekkel kapcsolatos hibák ezzel a szintaxissal jelennek meg, mindig 50000-es hibaszámmal rendelkeznek.
Hibák elhárítása a THROW használatával
A THROW utasítás egyszerűbb módszert kínál a kódhibák felvetésére. A hibáknak legalább 50000 hibaszámmal kell rendelkezniük.
DOB
A THROW többféleképpen különbözik a RAISERROR-tól:
- A THROW által kiváltott hibák mindig 16-os súlyosságúak.
- A THROW által visszaadott üzenetek nem kapcsolódnak a sys.sysmessages bejegyzéseihez.
- A THROW által okozott hibák csak akkor okoznak tranzakciós megszakítást, ha a SET XACT_ABORT ON beállítással együtt használják, és a munkamenet leáll.
THROW 50001, 'An Error Occured',0
Hibakódok rögzítése @@Error használatával
Az SQL Server-alkalmazásokban a legtöbb hagyományos hibakezelő kód a @@ERROR használatával lett létrehozva. A strukturált kivételkezelés az SQL Server 2005-ben lett bevezetve, és erős alternatívát kínál a @@ERROR használatára. Erről a következő leckében lesz szó. A meglévő SQL Server hibakezelő kód nagy része @@ERROR alapul, ezért fontos megérteni, hogyan kell vele dolgozni.
@@ERROR
@@ERROR egy rendszerváltozó, amely az utolsó hiba hibaszámát tartalmazza. A @@ERROR egyik jelentős kihívása, hogy a benne lévő érték gyorsan alaphelyzetbe áll az egyes további utasítások végrehajtásakor.
Vegyük például a következő kódot:
RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO
Előfordulhat, hogy a kód végrehajtásakor egy nyomtatott sztringben adja vissza a hibaszámot. A kód végrehajtásakor azonban a következőt adja vissza:
Msg 50000, Level 16, State 1, Line 1
Message
Error=0
A hiba felmerült, de a kinyomtatott üzenet a következő volt: "Error=0". A kimenet első sorában láthatja, hogy a hiba a vártnak megfelelően valójában 50000 volt, és egy üzenetet küldött a RAISERROR-nak. Ennek az az oka, hogy a RAISERROR utasítást követő HA utasítás végrehajtása sikeresen megtörtént, és a @@ERROR érték alaphelyzetbe állítását okozta. Ezért a @@ERROR használatakor fontos, hogy a hibaszámot azonnal rögzítse egy változóba, majd folytassa a feldolgozást a változóval.
Tekintse meg a következő kódot, amely ezt mutatja be:
DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));
A kód végrehajtásakor a következő kimenetet adja vissza:
Msg 50000, Level 16, State 1, Line 2
Message
Error=50000
A hibaszám helyesen lett jelentve.
Hibakezelés központosítása
A @@ERROR hibakezeléshez való használatával kapcsolatos másik jelentős probléma az, hogy nehéz központosítani a T-SQL-kódon belül. A hibakezelés általában a kódban szétszórtan végződik. A hibakezelést bizonyos mértékig @@ERROR használatával lehetne központosítani címkék és GOTO-utasítások használatával. Ezt azonban a legtöbb fejlesztő ma rossz kódolási gyakorlatnak tekinti.
Hibaértesítések létrehozása
Bizonyos hibakategóriák esetén a rendszergazdák SQL Server-riasztásokat hozhatnak létre, mert ezek bekövetkezése után azonnal értesítést szeretnének kapni. Ez a felhasználó által definiált hibaüzenetekre is vonatkozhat. Előfordulhat például, hogy egy tranzakciónapló kitöltésekor riasztást szeretne létrehozni. A riasztást gyakran használják arra, hogy felhívják a rendszergazdák figyelmét a nagy súlyosságú hibákra, mint például a 19-es vagy annál magasabb súlyosságúakra.
Riasztások emelése
Riasztások hozhatók létre adott hibaüzenetekhez. A riasztási szolgáltatás úgy működik, hogy visszahívási szolgáltatásként regisztrálja magát az eseménynaplózási szolgáltatással. Ez azt jelenti, hogy a riasztások csak naplózott hibákon működnek.
A hibát kétféleképpen lehet riasztásra késztetni: a NAPLÓVAL opció használatával a hiba kiadásakor, vagy az üzenet módosításával, amit a sp_altermessage végrehajtásával lehet naplózni. A WITH LOG beállítás csak az aktuális utasítást érinti. A sp_altermessage használata megváltoztatja a hiba viselkedését a jövőbeni használat során. A rendszerhibák sp_altermessage keresztül történő módosítása csak az SQL Server 2005 SP3 vagy az SQL Server 2008 SP1 verziótól lehetséges.