На жаль, з будь-якої причини ви не можете здійснити вбудовану конверсію в цьому контексті і , з будь-якої причини, RAISERROR
безпосередньо не підтримуєте float
.
Для повноти цієї відповіді ось відповідний фрагмент від MSDN , який я впевнений, ви вже бачили (зверніть увагу: це однаковий текст у всіх версіях документації з 2005 по 2012 роки):
Кожен параметр заміщення може бути локальною змінною або будь-яким з цих типів даних: tinyint , smallint , int , char , varchar , nchar , nvarchar , binary або varbinary .
Єдиним розумним рішенням, про яке я можу придумати, було б написати збережену процедуру для завершення RAISERROR
виклику. Ось відправна точка:
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
На жаль, не існує простого способу масштабування цього за довільною кількістю параметрів ... Це, ймовірно, можна зробити за допомогою згорнутого вкладеного динамічного SQL, який було б весело налагоджувати. Я залишу це як вправу для читача.
Я використовував sql_variant
припущення, що з причин однаковості коду однакова процедура застосовуватиметься всюди, навіть для типів значень, які підтримуються безпосередньо RAISERROR
. Також це може бути створено як тимчасово збережена процедура, якщо це доречно.
Ось як виглядає використання цієї процедури:
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;
Вихід:
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)
Таким чином, чистий результат полягає в тому, що ви не отримуєте здатності до форматування плавців (згорнути свої власні), але ви отримуєте можливість виводити їх (десятковий / числовий теж!), Зберігаючи можливість форматування для інших типів.