RAISERROR()
기본 단위 테스트 기능을 제공하기 위해 사용 하고 있지만 ( 여기 참조 ) FLOATs
오류 메시지 에 사용할 수 없기 때문에 실망 합니다. 플로트를 문자열로 캐스팅 할 수 있다는 것을 알고 있지만 RAISERROR
모든 단일 단위 테스트에서 사용 하고 있습니다. 모든 테스트마다 다른 코드 줄을 추가하고 싶지 않습니다. (내 단위 테스트는 이미 충분합니다!) 매개 변수 목록 내에서 인라인 캐스트 / 변환 을 수행하는 방법이 RAISERROR
있습니까? 아니면이 결함에 대한 다른 방법이 있습니까?
업데이트 :
궁극적으로 내가 할 수있는 일은 이것입니다.
RAISERROR('Unit Test FAILED! %f', 11, 0, @floatParm)
불행히도, RAISERROR
일반적으로 % f 또는 float를 처리하지 않습니다. 그래서 나는 이것을 대신해야합니다 :
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'
메시지 를 얻는다 . 왜 이것이 불법인지 이해하지 못합니다. 대신 여기에 사용할 수있는 또 하나의 “라이너”가 있습니까?
답변
불행히도 어떤 이유로 든 해당 컨텍스트에서 인라인 변환을 수행 할 수 없으며 어떤 이유로 든 다시 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)
따라서 결과는 부동 소수점에 대한 서식 기능을 얻지 못하고 (자신의 롤을 굴림) 다른 유형의 서식 기능을 유지하면서 10 진수 / 숫자를 출력하는 기능을 얻습니다.