Leider können Sie aus irgendeinem Grund in diesem Kontext keine Inline-Konvertierung durchführen und RAISERROR
unterstützen float
sie aus irgendeinem Grund nicht direkt .
Der Vollständigkeit halber ist hier der relevante Ausschnitt aus MSDN , den Sie sicher bereits gesehen haben (Hinweis: Es ist der gleiche Text in allen Versionen der Dokumentation von 2005 bis 2012):
Jeder Substitutionsparameter kann eine lokale Variable oder einer dieser Datentypen sein: tinyint , smallint , int , char , varchar , nchar , nvarchar , binär oder varbinary .
Die einzig vernünftige Lösung, die ich mir vorstellen kann, wäre, eine gespeicherte Prozedur zu schreiben, um den RAISERROR
Aufruf zu beenden . Hier ist ein Ausgangspunkt:
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
Leider gibt es keine einfache Möglichkeit, dies für eine beliebige Anzahl von Parametern zu skalieren ... Dies könnte wahrscheinlich mit verschlungenem verschachteltem dynamischem SQL geschehen, dessen Debuggen Spaß machen würde. Ich werde das als Übung für den Leser belassen.
Ich habe sql_variant
auf der Annahme , dass für die Code - Uniformität Gründe das gleiche Verfahren überall dort eingesetzt werden würde, auch für Werttypen , die sich direkt unterstützt RAISERROR
. Dies kann auch als temporär gespeicherte Prozedur erstellt werden, wenn dies angemessen ist.
So würde die Verwendung dieses Verfahrens aussehen:
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;
Ausgabe:
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)
Das Nettoergebnis ist also, dass Sie keine Formatierungsfähigkeit für Floats erhalten (rollen Sie Ihre eigenen), aber Sie erhalten die Möglichkeit, diese auszugeben (auch dezimal / numerisch!), Während Sie die Formatierungsfähigkeit für die anderen Typen beibehalten.