Thật không may, vì bất kỳ lý do gì, bạn không thể thực hiện chuyển đổi nội tuyến trong bối cảnh đó và RAISERROR
không hỗ trợ trực tiếp float
, vì bất kỳ lý do gì.
Để hoàn thiện câu trả lời này, đây là đoạn trích có liên quan từ MSDN , tôi chắc chắn bạn đã thấy (lưu ý: đó là cùng một văn bản trong tất cả các phiên bản của tài liệu từ năm 2005 đến 2012):
Mỗi tham số thay thế có thể là một biến cục bộ hoặc bất kỳ loại dữ liệu nào: tinyint , smallint , int , char , varchar , nchar , nvarchar , binary hoặc varbinary .
Giải pháp hợp lý duy nhất tôi có thể nghĩ đến là viết một thủ tục được lưu trữ để kết thúc RAISERROR
cuộc gọi. Đây là điểm khởi đầu:
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
Đáng buồn thay, không có cách nào dễ dàng để mở rộng quy mô này cho số lượng tham số tùy ý ... Có thể được thực hiện bằng cách sử dụng SQL động được lồng ghép phức tạp, sẽ rất thú vị khi gỡ lỗi. Tôi sẽ để nó như một bài tập cho người đọc.
Tôi đã sử dụng sql_variant
giả định rằng vì lý do thống nhất mã, quy trình tương tự sẽ được sử dụng ở mọi nơi, ngay cả đối với các loại giá trị được hỗ trợ trực tiếp bởi RAISERROR
. Ngoài ra, điều này có thể được tạo ra như một thủ tục lưu trữ tạm thời nếu phù hợp.
Đây là những gì sử dụng thủ tục này sẽ như thế nào:
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;
Đầu ra:
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)
Vì vậy, kết quả cuối cùng là bạn không có khả năng định dạng cho số float (tự cuộn), nhưng bạn cũng có được khả năng xuất chúng (số thập phân / số!) Trong khi vẫn giữ được khả năng định dạng cho các loại khác.