Fehlerbehandlung im T-SQL

Nicht immer funktioniert die Fehlerbehandlung so, wie man sie unterschwellig erwartet. Einige Entwickler sparen sich die Codierung einer Fehlerbehandlung, weil sie erwarten, dass eine Transaktion nach einem Fehler abgebrochen wird.

Das folgende Beispiel (was vielleicht der Inhalt einer Prozedur sein könnte) ist fehlerhaft, da das Commit auch bei einem Fehler erreicht wird:

BEGIN TRANSACTION;
INSERT ...;
INSERT ...;
INSERT ...;
COMMIT;

Die richtige Vorgehensweise wäre eine Kapselung der Insert-Statements mit einem "BEGIN TRY"-"END TRY" Block und Behandlung der Fehler im CATCH-Block.
Im folgenden noch einmal der Code zum nachvollziehen:

USE tempdb
GO
CREATE TABLE test2(f1 INT PRIMARY KEY);
GO
-- Part 1
BEGIN TRANSACTION;
  
INSERT INTO test2(f1) VALUES(1);
  
INSERT INTO test2(f1) VALUES(2);
  
INSERT INTO test2(f1) VALUES(2);
COMMIT;

SELECT *
FROM test2;

GO -- Part 2
TRUNCATE TABLE test2;

BEGIN TRANSACTION;
BEGIN Try
  
INSERT INTO test2(f1) VALUES(1);
  
INSERT INTO test2(f1) VALUES(2);
  
INSERT INTO test2(f1) VALUES(2);

END Try
BEGIN Catch
  
SELECT
        
ERROR_NUMBER() AS ErrorNumber
      
,ERROR_SEVERITY() AS ErrorSeverity
      
,ERROR_STATE() AS ErrorState
      
,ERROR_PROCEDURE() AS ErrorProcedure
      
,ERROR_LINE() AS ErrorLine
      
,ERROR_MESSAGE() AS ErrorMessage;

  
IF @@TRANCOUNT > 0
      
ROLLBACK;
END Catch;  
/* -- Falls es offene Transaktionen gibt, werden diese festgeschrieben */
IF @@TRANCOUNT > 0                
    
COMMIT TRANSACTION;

SELECT *
FROM test2;
GO

DROP TABLE test2;

  Fehlerbehandlung.txt