Tratamento de erros no SQL Server (TRY-CATCH)


Em linguagens de progamação como C# e Java, é comum o uso do bloco TRY-CATCH para tratar as exceções lançadas durante a execução das aplicações.

 Ao implementar Stored Procedures, Funções e Triggers, ou mesmo batches mais complexos, pode ser necessário tratar os possíveis erros ocorridos nos comandos.

 Até a versão 2000 do SQL Server, era necessário utilizar a função de sistema @@ERROR após cada um dos comando executado, pois o valor de retorno dessa função é reiniciao a cada comando executado.

 As versões 2005 e 2008 do SQL Server permitem implementar o tratamento de erros através do bloco TRY-CATCH, de maneira semelhante às linguagens de programação convecionais. 

 Este bloco é formado por dois sub-blocos:


TRY - contém os comandos necessários para executar a tarefa desejada
CATCH - contém os comandos para tratamento de possíveis erros ocorridos no bloco TRY

 Quando um erro ocorre no dentro do bloco TRY a execução é desviada para o bloco CATCH, o que permite continuar a execução do script ou interrompê-lo, de acordo com as necessidades do usuário e gravidade do erro gerado.

Sintaxe
A sintaxe definida para este bloco de comandos é a seguinte


BEGIN TRY
      [comandos SQL para execução de uma tarefa]
END TRY
BEGIN CATCH
      [comandos SQL para tratamento do erro]
END CATCH


Exemplo
Abaixo, temos um tratamento de erro realizado através deste bloco de comandos:


-- Criando tabela para teste
CREATE TABLE #teste (id int)

-- Adicionando restrição à tabela.
-- Somente IDs menores do que 10 serão aceitos
ALTER TABLE #teste ADD CONSTRAINT chkID CHECK (id < 10)


-- Executando a tarefa em transação
BEGIN TRANSACTION

BEGIN TRY
       
    INSERT INTO #teste VALUES (5)
    INSERT INTO #teste VALUES (2)
    INSERT INTO #teste VALUES (13)  -- Inserção de ID inválido

    COMMIT TRANSACTION -- Efetivando alterações na base

END TRY
BEGIN CATCH
   
    PRINT 'Erro ao executar script'
    ROLLBACK TRANSACTION -- Desfazendo as alterações na base
         
END CATCH

SELECT * FROM #teste

DROP TABLE #teste