Artikel

⚠️ THROW & das Semikolon – Die unsichtbare Stolperfalle in T-SQL

🧠 „Aber ich habe doch alles richtig gemacht!“ – Kennst Du das? Du schreibst eine stored procedure mit BEGIN TRY ... BEGIN CATCH ... THROW, aber SQL Server meldet: Falsche Syntax in der Nähe von 'THROW'. Die Lösung ist simpler als gedacht: ;THROW statt THROW. Klingt banal? Ist es auch – aber dieses feine Semikolon hat schon viele Nächte zerstört. Hier kommt die ganze Geschichte.
Das Problem: Syntaxerror im CATCH-Block
🤯
Dein Code sieht perfekt aus – aber SQL Server lehnt das THROW ab.
-- Diese Prozedur erzeugt einen Syntaxfehler!
CREATE PROC [dbo].[_01a_GetPropertiesForAllSQLEntries]
AS
SET NOCOUNT ON;
DECLARE @ManagedEntityRowId BIGINT
DECLARE db_cursor CURSOR FOR ...
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @ManagedEntityRowId

BEGIN TRY
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ReadProperties @ManagedEntityRowId, 'SQLServer'
FETCH NEXT FROM db_cursor INTO @ManagedEntityRowId
END
END TRY
BEGIN CATCH
IF CURSOR_STATUS('local', 'db_cursor') >= 0
BEGIN
CLOSE db_cursor
DEALLOCATE db_cursor
END
THROW; -- ❌ Msg 102, Level 15: Falsche Syntax in der Nähe von 'THROW'
END CATCH

CLOSE db_cursor
DEALLOCATE db_cursor
GO
⚠️ Fehlermeldung: Msg 102, Level 15, State 1, ... Falsche Syntax in der Nähe von 'THROW'.
🔍 Das passiert besonders häufig, wenn THROW direkt nach einem DEALLOCATE, CLOSE oder einem anderen Statement ohne abschließendes Semikolon kommt.
Die Lösung: Einfach ein Semikolon voranstellen
🔧
;THROW – das führende Semikolon trennt das vorherige Statement sauber ab.
BEGIN CATCH
IF CURSOR_STATUS('local', 'db_cursor') >= 0
BEGIN
CLOSE db_cursor
DEALLOCATE db_cursor
END
;THROW -- ✅ Jetzt wird es akzeptiert
END CATCH
🎯 Der Fix in der Praxis: Setze in jedem CATCH-Block, in dem THROW nicht das allererste Statement ist, ein Semikolon davor. ;THROW ist die sicherste Variante – unabhängig vom vorherigen Code.
📌 Hintergrund: In SQL Server muss jedes Statement korrekt terminiert sein. THROW ist im Vergleich zu RAISERROR strenger – es verlangt ein explizites Ende des vorherigen Befehls.
🤔
Warum? RAISERROR vs. THROW – ein kleiner Syntaxkrieg
⚔️
Die alte RAISERROR-Funktion war toleranter. THROW wurde mit einer strengeren Parser-Regel eingeführt.
-- RAISERROR (veraltet, aber oft noch gesehen)
RAISERROR('Fehler aufgetreten', 16, 1);

-- THROW (modern, seit SQL Server 2012)
;THROW 50000, 'Fehler aufgetreten', 1;

Der Parser von SQL Server erwartet, dass jedes Statement abgeschlossen ist. Steht THROW nach einem DEALLOCATE (das kein Semikolon hat), denkt der Parser: „Das THROW gehört noch zum DEALLOCATE dazu“ – und das ergibt keinen Sinn.

Ein führendes Semikolon sagt: „Hier ist ein harter Trennpunkt, das vorherige Statement ist zu Ende.“ – und plötzlich passt alles.

🧠 Merkregel: Immer ;THROW schreiben – dann ersparst Du Dir die Fehlersuche. Unabhängig davon, ob vorher ein Semikolon steht oder nicht.
🏁
Die finale, funktionierende Version
🎯
So sieht ein sauberer CATCH-Block mit THROW aus – inklusive Cursor-Aufräumung.
CREATE PROC [dbo].[_01a_GetPropertiesForAllSQLEntries]
AS
SET NOCOUNT ON;

DECLARE @ManagedEntityRowId BIGINT
DECLARE db_cursor CURSOR FOR
SELECT ManagedEntityRowId FROM [dbo].[SQLServer]

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @ManagedEntityRowId

BEGIN TRY
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ReadProperties @ManagedEntityRowId, 'SQLServer'
FETCH NEXT FROM db_cursor INTO @ManagedEntityRowId
END
END TRY
BEGIN CATCH
IF CURSOR_STATUS('local', 'db_cursor') >= 0
BEGIN
CLOSE db_cursor
DEALLOCATE db_cursor
END
;THROW -- ✅ Das führende Semikolon macht den Unterschied
END CATCH

CLOSE db_cursor
DEALLOCATE db_cursor
GO
💡 Best Practice: Setze auch nach jedem CLOSE, DEALLOCATE oder SET ein Semikolon – das ist ANSI-Standard und beugt solchen Problemen vor. Aber mindestens gilt: ;THROW im CATCH ist ein absolutes Muss.
⚠️
Weitere Fallstricke: THROW außerhalb von CATCH
🚨
THROW kann auch außerhalb von CATCH verwendet werden – aber auch dort lauern Syntaxregeln.
-- Außerhalb von CATCH: THROW benötigt Parameter
;THROW 50000, 'Benutzerdefinierter Fehler', 1;

-- Das geht nicht (keine Parameter):
;THROW; -- ❌ Fehler: Falsche Anzahl von Parametern

Zwei häufige Fehlerquellen:

  • THROW ohne Parameter außerhalb von CATCH → funktioniert nicht (nur innerhalb von CATCH darf THROW; allein stehen, um die originale Fehlermeldung weiterzuleiten).
  • Vergessenes Semikolon vor THROW → Syntaxfehler.
📖 Offizielle Doku: THROW akzeptiert entweder ;THROW (im CATCH, um die Exception erneut zu werfen) oder ;THROW error_number, message, state. Aber immer mit semantischem Trennzeichen davor.
🧠
Eselsbrücke: Punkt vor Strich – Semikolon vor THROW
🐘
Drei einfache Regeln, damit Du nie wieder über das THROW-Syntaxproblem stolperst.
  • Regel 1: Jeder CATCH-Block, der THROW enthält, schreibt ;THROW – nicht THROW.
  • Regel 2: Trenne nach Möglichkeit jedes T-SQL-Statement mit einem Semikolon ab (ANSI-Standard).
  • Regel 3: Wenn der Fehler auftritt: Setz ein Semikolon vor THROW und alles wird gut.
-- Gute Angewohnheit: Jedes Statement mit Semikolon beenden
DECLARE @i INT = 0;
SELECT @i = 1;
BEGIN TRY
PRINT 'Hallo';
END TRY
BEGIN CATCH
;THROW; -- Sicherheits-Semikolon
END CATCH
🎓 Viele Entwickler vernachlässigen Semikolons, weil SQL Server sie meist nicht zwingt. THROW ist der strenge Lehrer, der Dir zeigt, warum sie wichtig sind.

📌 Fazit für Deine tägliche Arbeit

Das THROW-Semikolon-Problem ist eine der unscheinbarsten, aber hartnäckigsten Stolperfallen in T-SQL. Es kostet Dich vielleicht 20 Minuten Debugging – bis Du die Lösung kennst. Danach wirst Du automatisch ;THROW schreiben, ohne nachzudenken.

Pro-Tipp: Nutze in Deinen SQL-Skripten und Prozeduren konsequent Semikolons als Terminatoren. Dann passiert Dir das Problem nie wieder – und Dein Code ist zukunftssicher (z.B. für SQL Server 2022 und die kommenden Versionen).

© 2026 powershelldba.de – deklarativ, mächtig, und mit dem richtigen Semikolon.
Nächster SQL Server – QUOTED_IDENTIFIER & ANSI_NULLS
Cookies user preferences
We use cookies to ensure you to get the best experience on our website. If you decline the use of cookies, this website may not function as expected.
Accept all
Decline all
Analytics
Tools used to analyze the data to measure the effectiveness of a website and to understand how it works.
Google Analytics
Advertisement
If you accept, the ads on the page will be adapted to your preferences.
Google Ad
Save