Infelizmente, por qualquer motivo, você não pode fazer uma conversão embutida nesse contexto e RAISERRORnão suporta diretamente floatnovamente, por qualquer motivo.
Para uma conclusão completa desta resposta, aqui está o trecho relevante do MSDN , que eu tenho certeza que você já viu (nota: é o mesmo texto em todas as versões da documentação de 2005 a 2012):
Cada parâmetro de substituição pode ser uma variável local ou qualquer um desses tipos de dados: tinyint , smallint , int , char , varchar , nchar , nvarchar , binário ou varbinário .
A única solução razoável em que posso pensar seria escrever um procedimento armazenado para encerrar a RAISERRORchamada. Aqui está um ponto de partida:
CREATE PROCEDURE [dbo].[MyRaiserror]
(
@message nvarchar(2048),
@severity tinyint,
@state tinyint,
@arg0 sql_variant = NULL
)
AS
BEGIN
DECLARE @msg nvarchar(MAX) = REPLACE(@message, '%f', '%s');
DECLARE @sql nvarchar(MAX) = N'RAISERROR(@msg, @severity, @state';
DECLARE @int0 int, @char0 nvarchar(MAX), @bin0 varbinary(MAX);
IF (@arg0 IS NOT NULL)
BEGIN
SET @sql += N', ';
IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('tinyint', 'smallint', 'int'))
BEGIN
SET @int0 = CONVERT(int, @arg0);
SET @sql += N'@int0';
END
ELSE IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('binary', 'varbinary'))
BEGIN
SET @bin0 = CONVERT(varbinary(MAX), @arg0);
SET @sql += N'@bin0';
END
ELSE
BEGIN
SET @char0 = CONVERT(nvarchar(MAX), @arg0);
SET @sql += N'@char0';
END
END
SET @sql += N');';
EXEC sp_executesql
@sql,
N'@msg nvarchar(2048), @severity tinyint, @state tinyint, @int0 int, @bin0 varbinary(MAX), @char0 nvarchar(MAX)',
@msg, @severity, @state, @int0, @bin0, @char0;
END
Infelizmente, não há uma maneira fácil de escalar isso para um número arbitrário de parâmetros ... Provavelmente isso poderia ser feito usando SQL dinâmico aninhado complicado, o que seria divertido de depurar. Vou deixar isso como um exercício para o leitor.
I utilizado sql_variantno pressuposto de que, por razões de uniformidade código, o mesmo procedimento poderia ser usado em todos os lugares, mesmo para tipos de valor que são suportados diretamente pelo RAISERROR. Além disso, isso pode ser criado como um procedimento armazenado temporário , se for apropriado.
Aqui está a aparência desse procedimento:
DECLARE @f float = 0.02345;
DECLARE @i int = 234;
DECLARE @s varchar(20) = 'asdfasdf';
DECLARE @b binary(4) = 0xA0B1C2D3;
DECLARE @d decimal(18, 9) = 152.2323;
DECLARE @n int = NULL;
EXEC [dbo].[MyRaiserror] N'Error message with no params.', 10, 1;
EXEC [dbo].[MyRaiserror] N'Float value = %f', 10, 1, @f;
EXEC [dbo].[MyRaiserror] N'Int value = %i', 10, 1, @i;
EXEC [dbo].[MyRaiserror] N'Character value = %s', 10, 1, @s;
EXEC [dbo].[MyRaiserror] N'Binary value = %#x', 10, 1, @b;
EXEC [dbo].[MyRaiserror] N'Decimal value = %f', 10, 1, @d;
EXEC [dbo].[MyRaiserror] N'Null value = %i', 10, 1, @n;
Resultado:
Error message with no params.
Float value = 0.02345
Int value = 234
Character value = asdfasdf
Binary value = 0xa0b1c2d3
Decimal value = 152.232300000
Null value = (null)
Portanto, o resultado líquido é que você não tem capacidade de formatação para carros alegóricos (faça o seu próprio), mas ganha a capacidade de produzi-los (decimal / numérico também!), Mantendo a capacidade de formatação para os outros tipos.