Использование FLOAT с RAISERROR

Я использую RAISERROR(), чтобы предоставить некоторые базовые функциональные возможности Unit Testing (как здесь ), но я разочарован неспособностью использовать FLOATs в сообщении об ошибке. Я знаю, что могу использовать float для строки, но я использую RAISERROR в каждом отдельном тесте, я не хочу добавлять еще одна строка кода для каждого теста. (Мои юнит-тесты уже достаточно многословны!) Есть ли способ выполнить inline cast /convert в RAISERROR список параметров? Или есть другой путь вокруг этого дефицита?

Update: Поэтому в конечном итоге я хотел бы сделать это:

RAISERROR('Unit Test FAILED! %f', 11, 0, @floatParm)

К сожалению, RAISERROR не обрабатывает% f или плавает вообще. Поэтому я должен сделать это вместо:

DECLARE @str VARCHAR(40) = CAST(@floatParm AS VARCHAR(40))
RAISERROR('Unit Test FAILED! %s', 11, 0, @str)

... который выглядит как беспорядок, когда он разбросаны по десяткам единиц тестов. Поэтому я хотел бы сварить это примерно так:

RAISERROR('Unit Test FAILED! %s', 11, 0, CAST(@floatParm AS VARCHAR(40))

Но это вызывает сообщение Incorrect syntax near 'CAST'. Я не понимаю, почему это незаконно, но это так. Есть ли еще один «один лайнер», который я мог бы использовать здесь?

10 голосов | спросил kmote 30 J0000006Europe/Moscow 2012, 00:45:08

1 ответ


9

К сожалению, по какой-либо причине вы не можете выполнить встроенное преобразование в этом контексте, а RAISERROR не поддерживает прямую ---- +: = 1 =: + ----, по какой-либо причине.

Для полноты этого ответа здесь приведен соответствующий фрагмент из MSDN , который, я уверен, вы уже видели (примечание: это один и тот же текст во всех версиях документации с 2005 по 2012 год):

  

Каждый параметр подстановки может быть локальной или любой из этих типов данных: tinyint , smallint , int , char , varchar , nchar , nvarchar , двоичный или varbinary .


Единственное разумное решение, о котором я могу думать, это написать хранимую процедуру для переноса вызова float. Вот начальная точка:

RAISERROR

К сожалению, нет простого способа масштабировать его для произвольного количества параметров ... Возможно, это можно было бы сделать с использованием свернутого вложенного динамического SQL, что было бы интересно отлаживать. Я оставлю это как упражнение для читателя.

Я использовал 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_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;

Таким образом, чистый результат заключается в том, что вы не получаете возможности форматирования для float (сворачивайте свои собственные), но вы получаете возможность выводить их (десятичная /цифровая, тоже!), сохраняя при этом способность форматирования для других типов.

ответил Jon Seigel 1 J000000Sunday12 2012, 19:57:10

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132