Verwerking van gestructureerde uitzonderingen implementeren
Nu u inzicht hebt in de aard van fouten en eenvoudige foutafhandeling in T-SQL, is het tijd om een geavanceerdere vorm van foutafhandeling te bekijken. Gestructureerde uitzonderingsafhandeling is geïntroduceerd in SQL Server 2005.
Hier ziet u hoe u deze kunt gebruiken en de voordelen en beperkingen kunt evalueren, waaronder het TRY CATCH-blok, de rol van foutafhandelingsfuncties en het verschil tussen ondervangbare en niet-toe te passen fouten. Ten slotte ziet u hoe fouten kunnen worden beheerd en waar nodig worden weergegeven.
Wat is TRY/CATCH-blokprogrammering?
De verwerking van gestructureerde uitzonderingen is krachtiger dan foutafhandeling op basis van de @@ERROR systeemvariabele. Hiermee kunt u voorkomen dat code wordt overspild met foutcodes en om die code voor foutafhandeling te centraliseren. Centralisatie van foutcodes betekent ook dat u zich meer kunt richten op het doel van de code in plaats van de foutafhandeling die deze bevat.
TRY-blok en CATCH-blok
Wanneer u gestructureerde uitzonderingsafhandeling gebruikt, wordt code die een fout kan veroorzaken binnen een TRY-blok geplaatst. TRY-blokken worden omsloten door de statements BEGIN TRY en END TRY.
Als er een ondervangbare fout optreedt- de meeste fouten kunnen worden opgevangen, wordt het uitvoeringsbeheer verplaatst naar het CATCH-blok. Het CATCH-blok is een reeks T-SQL-instructies die zijn ingesloten door BEGIN CATCH - en END CATCH-instructies .
Opmerking
Hoewel BEGIN CATCH en END TRY afzonderlijke instructies zijn, moet de BEGIN CATCH onmiddellijk de END TRY volgen.
Huidige beperkingen
Talen op hoog niveau bieden vaak een try/catch/final construct en worden vaak gebruikt om impliciet resources vrij te geven. Er is geen equivalent van een FINALLY-blok in T-SQL.
Het verschil begrijpen tussen te detecteren en niet-te-detecteren fouten.
Het is belangrijk om te beseffen dat, terwijl TRY/CATCH-blokken u in staat stellen een veel breder scala aan fouten te vangen dan met @@ERROR, kunt u niet elk type vangen.
Catchable versus niet-opvangbare fouten
Niet alle fouten kunnen worden opgevangen door TRY/CATCH-blokken binnen hetzelfde bereik waar het TRY/CATCH-blok bestaat. Fouten die niet in hetzelfde bereik kunnen worden opgevangen, kunnen vaak worden opgevangen in een omringend bereik. Het is bijvoorbeeld mogelijk dat u een fout niet kunt ondervangen in de opgeslagen procedure die het TRY/CATCH-blok bevat. De kans is echter groot dat u die fout in een TRY/CATCH-blok onderschept in de code die de opgeslagen procedure aanroept waarin de fout is opgetreden.
Veelvoorkomende niet-te-onderscheppen fouten
Veelvoorkomende voorbeelden van niet-opvangbare fouten zijn:
- Compileerfouten, zoals syntaxisfouten, die verhinderen dat een batch kan worden gecompileerd.
- Problemen met hercompilatie op statementniveau die meestal betrekking hebben op uitgestelde naamresolutie. U kunt bijvoorbeeld een opgeslagen procedure maken die verwijst naar een onbekende tabel. Er wordt alleen een fout gegenereerd wanneer de procedure de naam van de tabel probeert op te lossen naar een object-id.
Fouten opnieuwthrowen met behulp van THROW
Als de THROW-instructie wordt gebruikt in een CATCH-blok zonder parameters, zal de fout die ervoor heeft gezorgd dat de code het CATCH-blok binnenkwam, opnieuw worden opgeworpen. U kunt deze techniek gebruiken om logboekregistratie van fouten in de database te implementeren door fouten te onderscheppen en hun gegevens vast te leggen en vervolgens de oorspronkelijke fout naar de clienttoepassing te genereren, zodat deze daar kan worden verwerkt.
Hier is een voorbeeld van hoe een fout opnieuw gegooid kan worden.
BEGIN TRY
-- code to be executed
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE();
THROW
END CATCH
In sommige eerdere versies van SQL Server was er geen methode om een systeemfout te genereren. Hoewel THROW geen systeemfout kan specificeren om op te werpen, zullen systeem- en gebruikersfouten opnieuw opgeworpen worden wanneer THROW zonder parameters in een CATCH-blok wordt gebruikt.
Wat zijn functies voor foutafhandeling?
CATCH-blokken maken de foutgerelateerde informatie beschikbaar gedurende de duur van het CATCH-blok. Dit omvat subscopen, zoals opgeslagen procedures, die vanuit het CATCH-blok worden uitgevoerd.
Functies voor foutafhandeling
Denk eraan dat bij het programmeren met @@ERROR de waarde van de @@ERROR systeemvariabele opnieuw is ingesteld zodra de volgende instructie is uitgevoerd.
Een ander belangrijk voordeel van gestructureerde uitzonderingsafhandeling in T-SQL is dat er een reeks foutafhandelingsfuncties is opgegeven en dat deze hun waarden in het CATCH-blok behouden. Afzonderlijke functies bieden elke eigenschap van een veroorzaakte fout.
Dit betekent dat u algemene opgeslagen procedures voor foutafhandeling kunt schrijven die nog steeds toegang hebben tot de foutgerelateerde informatie.
- CATCH-blokken maken de foutgerelateerde informatie beschikbaar gedurende de duur van het CATCH-blok.
- @@Error wordt opnieuw ingesteld wanneer de volgende instructie wordt uitgevoerd.
Fouten in code beheren
Met SQL CLR-integratie kunt u beheerde code binnen SQL Server uitvoeren. Voor .NET-talen op hoog niveau, zoals C# en VB, zijn gedetailleerde verwerking van uitzonderingen beschikbaar. Fouten kunnen worden gedetecteerd met behulp van standaard .NET try/catch/finally-blokken.
Fouten in beheerde code
Over het algemeen wilt u mogelijk zoveel mogelijk fouten in beheerde code ondervangen. Het is echter belangrijk om te beseffen dat eventuele fouten die niet in de beheerde code worden verwerkt, worden doorgestuurd naar de aanroepende T-SQL-code. Wanneer een fout in beheerde code naar SQL Server wordt geretourneerd, lijkt deze een 6522-fout te zijn. Fouten kunnen worden genest en die specifieke fout zal de echte oorzaak van de fout verhullen.
Een andere zeldzame maar mogelijke oorzaak van fouten in beheerde code is dat de code een RAISERROR T-SQL-instructie kan uitvoeren via een SqlCommand-object.