Implementer T-SQL-fejlhåndtering

Fuldført

En fejl angiver et problem eller et bemærkelsesværdig problem, der opstår under en databasehandling. Fejl kan genereres af SQL Server-databaseprogrammet som svar på en hændelse eller fejl på systemniveau. eller du kan generere programfejl i din Transact-SQL-kode.

Elementer af fejl i databaseprogrammet

Uanset årsagen består alle fejl af følgende elementer:

  • Fejlnummer – Entydigt nummer, der identificerer den specifikke fejl.
  • Fejlmeddelelse – Tekst, der beskriver fejlen.
  • Alvorsgrad – Numerisk indikation af alvor fra 1 til 25.
  • State – Intern tilstandskode for databaseprogrammets tilstand.
  • Procedure – Navnet på den lagrede procedure eller udløser, hvor fejlen opstod.
  • Linjenummer – Hvilken sætning i batchen eller proceduren genererede fejlen.

Systemfejl

Systemfejl er foruddefinerede, og du kan få dem vist i systemvisningen sys.messages . Når der opstår en systemfejl, kan SQL Server udføre automatisk afhjælpningshandling, afhængigt af fejlens alvorsgrad. Når der f.eks. opstår en fejl med høj alvorsgrad, kan SQL Server gøre en database offline eller endda stoppe databaseprogrammets tjeneste.

Brugerdefinerede fejl

Du kan generere fejl i Transact-SQL kode for at reagere på programspecifikke betingelser eller for at tilpasse de oplysninger, der sendes til klientprogrammer som svar på systemfejl. Disse programfejl kan defineres indbygget, hvor de genereres, eller du kan foruddefinere dem i tabellen sys.messages sammen med de fejl, der er leveret af systemet. De fejlnumre, der bruges til brugerdefinerede fejl, skal være 50001 eller nyere.

Hvis du vil føje en brugerdefineret fejlmeddelelse til sys.messages, skal du bruge sp_addmessage. Brugeren af meddelelsen skal være medlem af de faste serverroller sysadmin eller serveradmin.

Dette er syntaksen for sp_addmessage:

sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg' 
     [ , [ @lang= ] 'language' ] 
     [ , [ @with_log= ] { 'TRUE' | 'FALSE' } ] 
     [ , [ @replace= ] 'replace' ]

Her er et eksempel på en brugerdefineret fejlmeddelelse ved hjælp af denne syntaks:

sp_addmessage 50001, 10, N’Unexpected value entered’;

Derudover kan du definere brugerdefinerede fejlmeddelelser. Medlemmer af serverrollen sysadmin kan også bruge en ekstra parameter @with_log. Når den er angivet til TRUE, registreres fejlen også i Windows-programloggen. Alle meddelelser, der skrives til Windows-programlogfilen, skrives også til SQL Server-fejlloggen. Vær fornuftig med brugen af indstillingen @with_log , fordi netværks- og systemadministratorer har en tendens til at synes om programmer, der er "chatty" i systemlogfilerne. Men hvis fejlen skal fanges af en besked, skal fejlen først skrives til Windows-programloggen.

Seddel

Det understøttes ikke at hæve systemfejl.

Meddelelser kan erstattes uden at slette dem først ved hjælp @replace af indstillingen = 'erstat'.

Meddelelserne kan tilpasses, og der kan tilføjes forskellige for det samme fejlnummer for flere sprog baseret på en language_id værdi.

Seddel

Engelske meddelelser er language_id 1033.

Hæv fejl ved hjælp af RAISERROR

Både PRINT og RAISERROR kan bruges til at returnere oplysninger eller advarsler til programmer. RAISERROR gør det muligt for programmer at udløse en fejl, der derefter kan blive fanget af opkaldsprocessen.

RAISERROR

Muligheden for at udløse fejl i T-SQL gør fejlhåndtering i programmet nemmere, fordi den sendes som enhver anden systemfejl. RAISERROR bruges til at:

  • Hjælp med at foretage fejlfinding af T-SQL-kode.
  • Kontrollér dataværdierne.
  • Returnerer meddelelser, der indeholder variabel tekst.

Seddel

Brug af en PRINT-sætning svarer til at udløse en fejl med alvorsgrad 10.

Her er et eksempel på en brugerdefineret fejlmeddelelse ved hjælp af RAISERROR.

RAISERROR (N'%s %d', -- Message text,
    10, -- Severity,
    1, -- State,
    N'Custom error message number',
    2)

Når den udløses, returneres:

Custom error message number 2

I det forrige eksempel er %d pladsholder for et tal, og %s er pladsholder for en streng. Derudover skal du være opmærksom på, at der ikke blev nævnt et meddelelsesnummer. Når der udløses fejl med meddelelsesstrenge ved hjælp af denne syntaks, har de altid fejlnummer 50000.

Hæv fejl ved hjælp af THROW

THROW-sætningen tilbyder en enklere metode til at hæve fejl i kode. Fejl skal have et fejlnummer på mindst 50000.

THROW

THROW adskiller sig fra RAISERROR på flere måder:

  • Fejl, der opstår af THROW, er altid alvorsgrad 16.
  • De meddelelser, der returneres af THROW, er ikke relateret til nogen poster i sys.sysmessages.
  • Fejl, der udløses af THROW, medfører kun afbrydelse af transaktionen, når de bruges sammen med SET XACT_ABORT ON, og sessionen afsluttes.
THROW 50001, 'An Error Occured',0

Hent fejlkoder ved hjælp af @@Error

Den mest traditionelle fejlhåndteringskode i SQL Server-programmer er oprettet ved hjælp af @@ERROR. Struktureret undtagelseshåndtering blev introduceret i SQL Server 2005 og er et stærkt alternativ til at bruge @@ERROR. Det vil blive diskuteret i den næste lektion. En stor mængde eksisterende SQL Server-fejlhåndteringskode er baseret på @@ERROR, så det er vigtigt at forstå, hvordan du arbejder med den.

@@ERROR

@@ERROR er en systemvariabel, der indeholder fejlnummeret for den seneste fejl, der er opstået. En væsentlig udfordring med @@ERROR er, at den værdi, den indeholder, hurtigt nulstilles, når hver ekstra sætning udføres.

Overvej f.eks. følgende kode:

RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO

Du kan forvente, at når koden udføres, returneres fejlnummeret i en udskrevet streng. Men når koden udføres, returneres:

Msg 50000, Level 16, State 1, Line 1
Message
Error=0

Fejlen blev udløst, men den udskrevne meddelelse var "Error=0". I den første linje i outputtet kan du se, at fejlen som forventet faktisk var 50000, hvor en meddelelse blev sendt til RAISERROR. Dette skyldes, at DEN IF-sætning, der følger efter RAISERROR-sætningen, blev udført korrekt og medførte, at den @@ERROR værdi blev nulstillet. Når du arbejder med @@ERROR, er det derfor vigtigt at registrere fejlnummeret i en variabel, så snart den udløses, og derefter fortsætte behandlingen med variablen.

Se følgende kode, der viser dette:

DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));

Når denne kode udføres, returneres følgende output:

Msg 50000, Level 16, State 1, Line 2
Message
Error=50000

Fejlnummeret er rapporteret korrekt nu.

Centralisering af fejlhåndtering

Et andet vigtigt problem med at bruge @@ERROR til fejlhåndtering er, at det er svært at centralisere inden for din T-SQL-kode. Fejlhåndtering ender som regel spredt over hele koden. Det ville i et vist omfang være muligt at centralisere fejlhåndtering ved hjælp af @@ERROR ved hjælp af mærkater og GOTO-sætninger. Dette ville dog blive ynkeligt af de fleste udviklere i dag som en dårlig kodningspraksis.

Opret fejlbeskeder

For visse kategorier af fejl kan administratorer oprette SQL Server-beskeder, fordi de ønsker at få besked, så snart disse opstår. Dette kan endda gælde for brugerdefinerede fejlmeddelelser. Det kan f.eks. være, at du vil udløse en besked, når en transaktionslog udfyldes. Besked bruges ofte til at gøre administratorer opmærksomme på fejl med høj alvorsgrad (f.eks. alvorsgrad 19 eller nyere).

Hæve beskeder

Der kan oprettes beskeder for bestemte fejlmeddelelser. Beskedtjenesten fungerer ved at registrere sig selv som en tilbagekaldstjeneste med hændelseslogføringstjenesten. Det betyder, at beskeder kun fungerer på logførte fejl.

Der er to måder at udløse en fejl på – du kan bruge indstillingen WITH LOG, når du udløser fejlen, eller du kan ændre meddelelsen for at få den logført ved at udføre sp_altermessage. Indstillingen WITH LOG påvirker kun den aktuelle sætning. Hvis du bruger sp_altermessage ændres fejlfunktionsmåden for al fremtidig brug. Ændring af systemfejl via sp_altermessage er kun muligt fra SQL Server 2005 SP3 eller SQL Server 2008 SP1 og fremefter.