Implementer behandling av T-SQL-feil

Fullført

En feil indikerer et problem eller et betydelig problem som oppstår under en databaseoperasjon. Feil kan genereres av SQL Server-databasemotoren som svar på en hendelse eller feil på systemnivå. eller du kan generere programfeil i Transact-SQL-koden.

Elementer av feil i databasemotoren

Uansett årsak består hver feil av følgende elementer:

  • Feilnummer - Unikt tall som identifiserer den bestemte feilen.
  • Feilmelding – Tekst som beskriver feilen.
  • Alvorsgrad - Numerisk indikasjon på alvor fra 1 til 25.
  • Tilstand – intern tilstandskode for databasemotorbetingelsen.
  • Prosedyre – navnet på den lagrede prosedyren eller utløseren der feilen oppstod.
  • Linjenummer – Hvilket uttrykk i bunken eller prosedyren genererte feilen.

Systemfeil

Systemfeil er forhåndsdefinert, og du kan vise dem i systemvisningen sys.messages . Når det oppstår en systemfeil, kan SQL Server utføre automatiske utbedringshandlinger, avhengig av alvorlighetsgraden av feilen. Når det for eksempel oppstår en alvorlighetsgradsfeil, kan SQL Server ta en database frakoblet eller til og med stoppe databasemotortjenesten.

Egendefinerte feil

Du kan generere feil i Transact-SQL kode for å svare på programspesifikke betingelser eller tilpasse informasjon som sendes til klientprogrammer som svar på systemfeil. Disse programfeilene kan defineres innebygd der de genereres, eller du kan forhåndsdefinere dem i tabellen sys.messages sammen med de systemdefinerte feilene. Feilnumrene som brukes for egendefinerte feil, må være 50001 eller nyere.

Hvis du vil legge til en egendefinert feilmelding i sys.messages, bruker du sp_addmessage. Brukeren for meldingen må være medlem av de faste serverrollene for 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 egendefinert feilmelding ved hjelp av denne syntaksen:

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

I tillegg kan du definere egendefinerte feilmeldinger, medlemmer av sysadmin-serverrollen kan også bruke en ekstra parameter, @with_log. Når den er satt til SANN, registreres også feilen i Windows-programloggen. Alle meldinger som er skrevet til Windows-programloggen, skrives også til feilloggen for SQL Server. Vær fornuftig med bruken av @with_log alternativet fordi nettverks- og systemadministratorer har en tendens til å mislike programmer som er "chatty" i systemloggene. Hvis feilen imidlertid må fanges opp av et varsel, må feilen først skrives til Windows-programloggen.

Merk deg

Heving av systemfeil støttes ikke.

Meldinger kan erstattes uten å slette dem først ved hjelp @replace av alternativet = «erstatt».

Meldingene kan tilpasses, og forskjellige kan legges til for samme feilnummer for flere språk, basert på en language_id verdi.

Merk deg

Engelske meldinger er language_id 1033.

Opphøy feil ved hjelp av RAISERROR

Både PRINT og RAISERROR kan brukes til å returnere informasjon eller advarsler til programmer. RAISERROR gjør det mulig for programmer å opprette en feil som deretter kan fanges opp av anropsprosessen.

RAISERROR

Muligheten til å ta opp feil i T-SQL gjør feilbehandling i programmet enklere, fordi det sendes som alle andre systemfeil. RAISERROR brukes til å:

  • Hjelp til med å feilsøke T-SQL-kode.
  • Kontroller verdiene for data.
  • Returner meldinger som inneholder variabel tekst.

Merk deg

Bruk av en PRINT-setning ligner på å øke en alvorsfeil 10.

Her er et eksempel på en egendefinert feilmelding ved hjelp av RAISERROR.

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

Når den utløses, returneres den:

Custom error message number 2

I forrige eksempel er %d en plassholder for et tall, og %s er en plassholder for en streng. I tillegg bør du være oppmerksom på at et meldingsnummer ikke ble nevnt. Når feil med meldingsstrenger utløses ved hjelp av denne syntaksen, har de alltid feilnummer 50000.

Opphøy feil ved hjelp av THROW

THROW-setningen tilbyr en enklere metode for å øke feil i kode. Feil må ha et feilnummer på minst 50 000.

UNNTAK

THROW skiller seg fra RAISERROR på flere måter:

  • Feil som oppstår av THROW er alltid alvorsgrad 16.
  • Meldingene som returneres av THROW, er ikke relatert til noen oppføringer i sys.sysmessages.
  • Feil som oppstår av THROW, fører bare til at transaksjonen avbrytes når den brukes sammen med SET XACT_ABORT ON, og økten avsluttes.
THROW 50001, 'An Error Occured',0

Registrere feilkoder ved hjelp av @@Error

De fleste tradisjonelle feilbehandlingskoder i SQL Server-programmer er opprettet ved hjelp av @@ERROR. Strukturert unntakshåndtering ble innført i SQL Server 2005 og gir et sterkt alternativ til å bruke @@ERROR. Det vil bli diskutert i neste leksjon. En stor mengde eksisterende SQL Server-feilhåndteringskode er basert på @@ERROR, så det er viktig å forstå hvordan du arbeider med den.

@@ERROR

@@ERROR er en systemvariabel som inneholder feilnummeret for den siste feilen som har oppstått. En viktig utfordring med @@ERROR er at verdien den har, raskt tilbakestilles etter hvert som hver ekstra setning utføres.

Vurder for eksempel 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 kjøres, returneres feilnummeret i en utskrevet streng. Men når koden kjøres, returneres den:

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

Feilen ble utløst, men meldingen som ble skrevet ut, var «Feil=0». I den første linjen i utdataene kan du se at feilen, som forventet, faktisk var 50000, med en melding sendt til RAISERROR. Dette skyldes at HVIS-setningen som følger RAISERROR-setningen ble utført, og førte til at @@ERROR-verdien ble tilbakestilt. Når du arbeider med @@ERROR, er det derfor viktig å registrere feilnummeret i en variabel så snart den er opphøyd, og deretter fortsette behandlingen med variabelen.

Se på følgende kode som demonstrerer 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 koden kjøres, returnerer den følgende utdata:

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

Feilnummeret rapporteres riktig nå.

Sentralisere feilbehandling

Et annet viktig problem med å bruke @@ERROR for feilbehandling, er at det er vanskelig å sentralisere i T-SQL-koden. Feilbehandling har en tendens til å ende opp spredt over hele koden. Det ville være mulig å sentralisere feilbehandling ved hjelp av @@ERROR til en viss grad, ved hjelp av etiketter og GOTO-setninger. Dette ville imidlertid bli mislikt av de fleste utvikleres i dag som en dårlig kodingspraksis.

Opprette feilvarsler

Administratorer kan opprette SQL Server-varsler fordi de ønsker å bli varslet så snart disse oppstår, for enkelte feilkategorier kan opprettes. Dette kan også gjelde for brukerdefinerte feilmeldinger. Det kan for eksempel hende du vil heve et varsel når en transaksjonslogg fylles ut. Varsling brukes vanligvis til å gjøre vanlige alvorlighetsgradsfeil (for eksempel alvorsgrad 19 eller høyere) oppmerksomme på administratorer.

Heve varsler

Varsler kan opprettes for bestemte feilmeldinger. Varslingstjenesten fungerer ved å registrere seg som en tilbakeringingstjeneste med hendelsesloggtjenesten. Dette betyr at varsler bare fungerer på påloggede feil.

Det finnes to måter å få en feil til å heve et varsel på. Du kan bruke alternativet WITH LOG når du øker feilen, eller meldingen kan endres for å gjøre den logget ved å kjøre sp_altermessage. ALTERNATIVET WITH LOG påvirker bare gjeldende setning. Bruk av sp_altermessage endrer feilvirkemåten for all fremtidig bruk. Endring av systemfeil via sp_altermessage er bare mulig fra SQL Server 2005 SP3 eller SQL Server 2008 SP1 og fremover.