T-SQL

Výpis chyb z CATCH bloku

Při psaní složitějších rutin v T-SQL a zejména při zanořování uložených procedur a dalších pokročilých scénářích je určitě na místě předejít nekontrolovaným chybám využitím konstrukce TRY & CATCH. Pokud nějaká chyba přeci jen nastane a zachytíme ji v CATCH bloku, potřebujeme vědět, o jakou chybu se jedná. Pokud nepošleme chybu dále z CATCH bloku pomocí THROW, je na nás, abychom pomocí systémových funkcí získali popis chyby a dále s ním pracovali, buď vrácením uživateli nebo zapsáním do logu. A není nic rozumnějšího, než vypisování chyb sjednotit pro celé databázové řešení a mít jednotný výstupní formát, který bude jak jednoduše strojově zpracovatelný, tak i uživatelsky přívětivý a přidá nějakou tu informaci navíc.

Jednou z elegantních možností je, že pro sestavení chybové zprávy vytvoříme samostatnou proceduru, kterou budeme následně volat z CATCH bloku bez dalšího zbytečného kódu.

Procedura pro sestavení chybové zprávy může vypadat například takto:

CREATE OR ALTER PROCEDURE [dbo].[FireError]
AS
BEGIN    
    
	DECLARE @ErrorMessage NVARCHAR(MAX)
	DECLARE @ErrorSeverity INT
	DECLARE @ErrorState INT

	SET @ErrorSeverity = ERROR_SEVERITY()
	SET @ErrorState = ERROR_STATE()

    SET @ErrorMessage =  
        '|' + ISNULL(CAST(ERROR_NUMBER() AS NVARCHAR(10)), 'ERROR_NUMBER') +  ' | ' +
              ISNULL(CAST(@ErrorSeverity AS NVARCHAR(10)), 'ERROR_SEVERITY') +  ' | ' +
              ISNULL(CAST(@ErrorState AS NVARCHAR(10)), 'ERROR_STATE') +  ' | ' +
              ISNULL(ERROR_PROCEDURE(), 'CALLED_OUTSIDE_STORED_PROCEDURE') +  ' | ' +
              ISNULL(CAST(ERROR_LINE() AS NVARCHAR(10)), 'ERROR_LINE') +  ' | ' +
              ISNULL(ERROR_MESSAGE(), 'ERROR_MESSAGE')  + 
        '|'
    
	RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)

	RETURN 0

END
GO

Tělo procedury pouze volá systémové funkce pro získání popisu chyby a formátuje jejich výstup do uživatelský přívětivé podoby.

Proceduru pak můžeme volat v CATCH bloku takto:

BEGIN TRY

	PRINT 1/0

END TRY
BEGIN CATCH

	EXEC [dbo].[FireError]

END CATCH
GO

Na obrázku je vidět, jak vypadá zformátovaná chybová zpráva. A barevně je vyznačeno jedno drobné vylepšení, které jsme do sestavení chybové zprávy přidali: pokud již nastane v SQL Serveru uživatelská chyba, často první po čem budeme pátrat je, zda se jednalo o ad-hoc kód nebo došlo k chybě v uložené proceduře. Zde vidíme, že k chybě došlo v kódu mimo uloženou proceduru.

Pojďme nyní otestovat stejnou chybu, ale vyvolejme ji v těle testovací uložené procedury:

CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN

	BEGIN TRY

		PRINT 1/0

	END TRY
	BEGIN CATCH

		EXEC [dbo].[FireError]
	
	END CATCH
    
END
GO

EXEC [dbo].[TestProcedure]
GO

Nyní nám chybová zpráva přímo ukazuje název uložené procedury, ve které k chybě došlo a vím tak rovnou, kam do databáze sáhnout a chybu opravit.

Leave a Reply

Your email address will not be published. Required fields are marked *