Você pode ser capaz de relançá-lo assim:
..
END TRY
BEGIN CATCH
DECLARE @errnum int;
SELECT @errnum = ERROR_NUMBER();
RAISERROR (@errnum, 16, 1);
END CATCH
No entanto, você provavelmente perderá o significado devido aos espaços reservados %s etc nas linhas sys.messages para ERROR_NUMBER()
Você pode fazer algo assim para incluir o número e relançar a mensagem original
..
END TRY
BEGIN CATCH
DECLARE @errnum nchar(5), @errmsg nvarchar(2048);
SELECT
@errnum = RIGHT('00000' + ERROR_NUMBER(), 5),
@errmsg = @errnum + ' ' + ERROR_MESSAGE();
RAISERROR (@errmsg, 16, 1);
END CATCH
Os primeiros 5 caracteres são o número original.
Mas se você tiver código aninhado, acabará com "00123 00456 Texto de erro".
Pessoalmente, eu só lido com números de exceção SQL para separar meus erros (50000) dos erros do mecanismo (por exemplo, parâmetros ausentes) onde meu código não é executado.
Finalmente, você pode passar o valor de retorno.
Fiz uma pergunta sobre isso:Manipulação de erros do SQL Server:exceções e o contrato do cliente de banco de dados