Acabei de me surpreender com algo em TSQL. Eu pensei que se xact_abort estivesse ligado, chamando algo como
raiserror('Something bad happened', 16, 1);
interromperia a execução do procedimento armazenado (ou qualquer lote).
Mas minha mensagem de erro do ADO.NET provou o contrário. Recebi a mensagem de erro raiserror na mensagem de exceção, além da próxima coisa que quebrou depois disso.
Esta é a minha solução alternativa (que é meu hábito de qualquer maneira), mas não parece que seja necessário:
if @somethingBadHappened
begin;
raiserror('Something bad happened', 16, 1);
return;
end;
Os documentos dizem o seguinte:
Quando SET XACT_ABORT está ON, se uma instrução Transact-SQL gerar um erro em tempo de execução, a transação inteira será encerrada e revertida.
Isso significa que devo usar uma transação explícita?
sql
sql-server
tsql
Eric Z Beard
fonte
fonte
RAISERROR
, de fato, encerrará a execução se a gravidade for definida como 17 ou 18, em vez de 16.RAISERROR
, de fato, não encerrará a execução se a gravidade for definida como 17 ou 18, em vez de 16.Respostas:
Este é o By Design TM , como você pode ver no Connect pela resposta da equipe do SQL Server a uma pergunta semelhante:
Sim, isso é um pouco problemático para alguns que esperavam que
RAISERROR
com uma gravidade alta (como16
) fosse o mesmo que um erro de execução SQL - não é.Sua solução alternativa é exatamente o que você precisa fazer, e usar uma transação explícita não tem nenhum efeito no comportamento que você deseja alterar.
fonte
Se você usar um bloco try / catch, um número de erro raiserror com gravidade 11-19 fará com que a execução pule para o bloco catch.
Qualquer gravidade acima de 16 é um erro do sistema. Para demonstrar o código a seguir, configura um bloco try / catch e executa um procedimento armazenado que presumimos que falhará:
suponha que temos uma tabela [dbo]. [Erros] para manter os erros pressupõe que temos um procedimento armazenado [dbo]. [AssumeThisFails] que falhará quando for executado
fonte
Use
RETURN
imediatamente depoisRAISERROR()
e ele não executará o procedimento posteriormente.fonte
rollback transaction
antes de ligarreturn
.Conforme indicado nos documentos para
SET XACT_ABORT
, aTHROW
instrução deve ser usada em vez deRAISERROR
.Os dois se comportam de maneira um pouco diferente . Mas quando
XACT_ABORT
está definido como ON, você deve sempre usar oTHROW
comando.fonte