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.
