T-SQL Ninja #03

TRY CATCH

Was ist try-catch?

Wer von euch programmiert, der kennt trycatch-Blöcke zur Behandlung von Ausnahmen. Konstrukte wie dieses durch die man im Code nicht einfach auf Fehler läuft und den Code abbricht, sondern auf Ausnahmen reagieren kann, sind in der Programmier-Welt zwar alltäglich, im SQL-Standard jedoch nicht vorgesehen.

Wofür könnt ihr try-catch verwenden?

Trycatch-Blöcke sind genau wie bei der Programmierung auch im SQL-Bereich immer dann nützlich, wenn ihr auf Fehler in einer besonderen Art reagieren möchtet ohne dass Euer Code mit einem Fehler beendet wird. Besonders oft verwende ich try-catch-Blöcke, wenn es darum geht, beispielsweise für eine Demo oder einen Test eine (temporäre) Tabelle zu erzeugen und wieder aufzuräumen. In geraumer Vorzeit sah mein Code um temporäre Tabellen zu entfernen dann beispielsweise wie folgt aus:


IF OBJECT_ID('tempdb..#OrdersTemp', 'U') IS NOT NULLBEGIN DROP TABLE #OrdersTemp;END
SELECT
     O.[OrderID]
    ,O.[OrderDate]
    ,O.[ExpectedDeliveryDate]
    ,Ol.[StockItemID]
    ,Ol.[Description]
    ,Ol.[Quantity]
    ,Ol.[UnitPrice]
INTO #OrdersTemp
FROM[Sales].[Orders] AS O
LEFT JOIN[Sales].[OrderLines] AS Ol ON O.[OrderID] = Ol.[OrderID]

Und wenn ich ganz ehrlich bin, konnte ich mich nie an das tempdb mit den zwei Punkten beim Abfragen der Objekt-ID gewöhnen (und musste die Syntax auch für diesen Beitrag nochmal extra nachlesen). Viel einfacher wurde das Leben da mit SQL Server 2016, als Microsoft sich entschied im SQL Server eine Drop if exists-Syntax einzuführen, die in anderen Systemen schon länger möglich ist. Danach sahen meine Abfragen dann so aus:

DROP TABLE IF EXISTS #OrdersTemp
SELECT
     O.[OrderID]
    ,O.[OrderDate]
    ,O.[ExpectedDeliveryDate]
    ,Ol.[StockItemID]
    ,Ol.[Description]
    ,Ol.[Quantity]
    ,Ol.[UnitPrice]
INTO #OrdersTemp
FROM
[Sales].[Orders] AS O
LEFT JOIN
[Sales].[OrderLines] AS Ol ON O.[OrderID] = Ol.[OrderID]

Wenn ihr aber gelegentlich zwischen den Versionen springt, dann könnte es sein, dass es euch (wie mir) schwerfällt, euch zu merken, welche der beiden Versionen ihr verwenden müsst. Meine Abfragen sehen deshalb meistens so aus:

BEGIN TRY DROP TABLE #OrdersTemp END TRY BEGIN CATCH END CATCH
SELECT
     O.[OrderID]
    ,O.[OrderDate]
    ,O.[ExpectedDeliveryDate]
    ,Ol.[StockItemID]
    ,Ol.[Description]
    ,Ol.[Quantity]
    ,Ol.[UnitPrice]
INTO #OrdersTemp
FROM
[Sales].[Orders] AS O
LEFT JOIN
[Sales].[OrderLines] AS Ol ON O.[OrderID] = Ol.[OrderID]

Als Mensch mit Programmierhintergrund fällt es mir einfach immer am leichtesten mir eine TryCatch-Syntax zu merken… Natürlich könnt ihr mit TryCatch-Blöcken noch viel spannendere Dinge tun, beispielsweise in gespeicherten Prozeduren auf Fehler reagieren und Fehler nicht (wie in diesem Beispiel) ignorieren sondern stattdessen sauber behandeln und ein Log für fehlgeschlagene gespeicherte Prozeduren führen.

Refrenzen

Ninja-Notebooks @ GitHub

2 Gedanken zu „TRY CATCH

  1. TRY..CATCH ist tatsächlich eines der Konstrukte, wo ich immer wieder spicken muss. Gebe ich gerne zu.
    Spanned ist ja eigentlich, was man noch alles im CATCH Block abfangen kann oder wie es ausschaut, wenn ich TRY..CATCH mit dem Thema explizite Transaktion kombiniere.

    Vielleicht haut der Ninja ja irgendwann dazu auch noch mal was raus 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.