T-SQL-hibakezelés implementálása

Befejeződött

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.