Antworten:
Wenn Sie SQL Server 2012 und höher verwenden, können Sie verwenden FORMATMESSAGE
. z.B.
DECLARE @s NVARCHAR(50) = 'World';
DECLARE @d INT = 123;
SELECT FORMATMESSAGE('Hello %s, %d', @s, @d)
-- RETURNS 'Hello World, 123'
Weitere Beispiele aus MSDN: FORMATMESSAGE
SELECT FORMATMESSAGE('Signed int %i, %d %i, %d, %+i, %+d, %+i, %+d', 5, -5, 50, -50, -11, -11, 11, 11);
SELECT FORMATMESSAGE('Signed int with leading zero %020i', 5);
SELECT FORMATMESSAGE('Signed int with leading zero 0 %020i', -55);
SELECT FORMATMESSAGE('Unsigned int %u, %u', 50, -50);
SELECT FORMATMESSAGE('Unsigned octal %o, %o', 50, -50);
SELECT FORMATMESSAGE('Unsigned hexadecimal %x, %X, %X, %X, %x', 11, 11, -11, 50, -50);
SELECT FORMATMESSAGE('Unsigned octal with prefix: %#o, %#o', 50, -50);
SELECT FORMATMESSAGE('Unsigned hexadecimal with prefix: %#x, %#X, %#X, %X, %x', 11, 11, -11, 50, -50);
SELECT FORMATMESSAGE('Hello %s!', 'TEST');
SELECT FORMATMESSAGE('Hello %20s!', 'TEST');
SELECT FORMATMESSAGE('Hello %-20s!', 'TEST');
SELECT FORMATMESSAGE('Hello %20s!', 'TEST');
ANMERKUNGEN:
FORMATMESSAGE
als (harmloser) Fehler angezeigtmsg_number
.
string.Format
In T-SQL gibt es keine Funktionalität im Stil, dies ist die nächstgelegene, die Sie erhalten.
Schauen Sie sich xp_sprintf an . Beispiel unten.
DECLARE @ret_string varchar (255)
EXEC xp_sprintf @ret_string OUTPUT,
'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2'
PRINT @ret_string
Ergebnis sieht so aus:
INSERT INTO table1 VALUES (1, 2)
Ich habe gerade ein Problem mit der maximalen Größe (maximal 255 Zeichen) der Zeichenfolge gefunden, sodass Sie eine alternative Funktion verwenden können:
create function dbo.fnSprintf (@s varchar(MAX),
@params varchar(MAX), @separator char(1) = ',')
returns varchar(MAX)
as
begin
declare @p varchar(MAX)
declare @paramlen int
set @params = @params + @separator
set @paramlen = len(@params)
while not @params = ''
begin
set @p = left(@params+@separator, charindex(@separator, @params)-1)
set @s = STUFF(@s, charindex('%s', @s), 2, @p)
set @params = substring(@params, len(@p)+2, @paramlen)
end
return @s
end
Um das gleiche Ergebnis wie oben zu erhalten, rufen Sie die Funktion wie folgt auf:
print dbo.fnSprintf('INSERT INTO %s VALUES (%s, %s)', 'table1,1,2', default)
Ich habe eine benutzerdefinierte Funktion erstellt, um die Funktion string.format nachzuahmen. Du kannst es benutzen.
Es gibt einen Weg, aber er hat seine Grenzen. Sie können die FORMATMESSAGE()
Funktion verwenden. Sie können eine Zeichenfolge mit einer Formatierung formatieren, die der printf()
Funktion in C ähnelt .
Die größte Einschränkung besteht jedoch darin, dass nur Nachrichten in der Tabelle sys.messages verwendet werden. Hier ist ein Artikel darüber: microsoft_library_ms186788
Es ist eine Schande, dass es keinen einfacheren Weg gibt, dies zu tun, da es Zeiten gibt, in denen Sie einen String / Varchar in der Datenbank formatieren möchten. Hoffentlich möchten Sie eine Zeichenfolge nur auf standardmäßige Weise formatieren und können die sys.messages
Tabelle verwenden.
Zufälligerweise können Sie die RAISERROR()
Funktion auch mit einem sehr geringen Schweregrad verwenden. In der Dokumentation für Raiseerror wird dies sogar erwähnt, aber die Ergebnisse werden nur gedruckt. Mit dem resultierenden Wert könnten Sie also nichts anfangen (soweit ich weiß).
Viel Glück!
FORMATMESSAGE()
ist falsch, jedoch verständlich, da sie nicht dokumentiert ist, aber eine beliebige Zeichenfolge als ersten Parameter akzeptiert . Siehe diese Antwort von @ g2server .
Raw t-sql ist für die Zeichenfolgenmanipulation auf CHARINDEX (), PATINDEX (), REPLACE () und SUBSTRING () beschränkt. Mit SQL Server 2005 und höher können Sie jedoch benutzerdefinierte Funktionen einrichten, die in .Net ausgeführt werden. Das Einrichten einer UDF für string.format () sollte daher nicht zu schwierig sein.
Noch eine Idee.
Obwohl dies keine universelle Lösung ist - es ist einfach und funktioniert zumindest für mich :)
Für einen Platzhalter {0}:
create function dbo.Format1
(
@String nvarchar(4000),
@Param0 sql_variant
)
returns nvarchar(4000)
as
begin
declare @Null nvarchar(4) = N'NULL';
return replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));
end
Für zwei Platzhalter {0} und {1}:
create function dbo.Format2
(
@String nvarchar(4000),
@Param0 sql_variant,
@Param1 sql_variant
)
returns nvarchar(4000)
as
begin
declare @Null nvarchar(4) = N'NULL';
set @String = replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));
return replace(@String, N'{1}', cast(isnull(@Param1, @Null) as nvarchar(4000)));
end
Für drei Platzhalter {0}, {1} und {2}:
create function dbo.Format3
(
@String nvarchar(4000),
@Param0 sql_variant,
@Param1 sql_variant,
@Param2 sql_variant
)
returns nvarchar(4000)
as
begin
declare @Null nvarchar(4) = N'NULL';
set @String = replace(@String, N'{0}', cast(isnull(@Param0, @Null) as nvarchar(4000)));
set @String = replace(@String, N'{1}', cast(isnull(@Param1, @Null) as nvarchar(4000)));
return replace(@String, N'{2}', cast(isnull(@Param2, @Null) as nvarchar(4000)));
end
und so weiter...
Ein solcher Ansatz ermöglicht es uns, diese Funktionen in der SELECT-Anweisung und mit Parametern der Datentypen nvarchar, number, bit und datetime zu verwenden.
Beispielsweise:
declare @Param0 nvarchar(10) = N'IPSUM' ,
@Param1 int = 1234567 ,
@Param2 datetime2(0) = getdate();
select dbo.Format3(N'Lorem {0} dolor, {1} elit at {2}', @Param0, @Param1, @Param2);
Ich denke, es gibt eine kleine Korrektur bei der Berechnung der Endposition.
Hier ist die richtige Funktion
**>>**IF OBJECT_ID( N'[dbo].[FormatString]', 'FN' ) IS NOT NULL
DROP FUNCTION [dbo].[FormatString]
GO
/***************************************************
Object Name : FormatString
Purpose : Returns the formatted string.
Original Author : Karthik D V http://stringformat-in-sql.blogspot.com/
Sample Call:
SELECT dbo.FormatString ( N'Format {0} {1} {2} {0}', N'1,2,3' )
*******************************************/
CREATE FUNCTION [dbo].[FormatString](
@Format NVARCHAR(4000) ,
@Parameters NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
--DECLARE @Format NVARCHAR(4000), @Parameters NVARCHAR(4000) select @format='{0}{1}', @Parameters='hello,world'
DECLARE @Message NVARCHAR(400), @Delimiter CHAR(1)
DECLARE @ParamTable TABLE ( ID INT IDENTITY(0,1), Parameter VARCHAR(1000) )
Declare @startPos int, @endPos int
SELECT @Message = @Format, @Delimiter = ','**>>**
--handle first parameter
set @endPos=CHARINDEX(@Delimiter,@Parameters)
if (@endPos=0 and @Parameters is not null) --there is only one parameter
insert into @ParamTable (Parameter) values(@Parameters)
else begin
insert into @ParamTable (Parameter) select substring(@Parameters,0,@endPos)
end
while @endPos>0
Begin
--insert a row for each parameter in the
set @startPos = @endPos + LEN(@Delimiter)
set @endPos = CHARINDEX(@Delimiter,@Parameters, @startPos)
if (@endPos>0)
insert into @ParamTable (Parameter)
select substring(@Parameters,@startPos,@endPos - @startPos)
else
insert into @ParamTable (Parameter)
select substring(@Parameters,@startPos,4000)
End
UPDATE @ParamTable SET @Message =
REPLACE ( @Message, '{'+CONVERT(VARCHAR,ID) + '}', Parameter )
RETURN @Message
END
Go
grant execute,references on dbo.formatString to public
Hier ist meine Version. Kann erweitert werden, um mehr Parameter aufzunehmen, und kann die Formatierung basierend auf dem Typ erweitern. Derzeit werden nur Datums- und Datums- / Uhrzeittypen formatiert.
Beispiel:
select dbo.FormatString('some string %s some int %s date %s','"abcd"',100,cast(getdate() as date),DEFAULT,DEFAULT)
select dbo.FormatString('some string %s some int %s date time %s','"abcd"',100,getdate(),DEFAULT,DEFAULT)
Ausgabe:
some string "abcd" some int 100 date 29-Apr-2017
some string "abcd" some int 100 date time 29-Apr-2017 19:40
Funktionen:
create function dbo.FormatValue(@param sql_variant)
returns nvarchar(100)
begin
/*
Tejasvi Hegde, 29-April-2017
Can extend formatting here.
*/
declare @result nvarchar(100)
if (SQL_VARIANT_PROPERTY(@param,'BaseType') in ('date'))
begin
select @result = REPLACE(CONVERT(CHAR(11), @param, 106), ' ', '-')
end
else if (SQL_VARIANT_PROPERTY(@param,'BaseType') in ('datetime','datetime2'))
begin
select @result = REPLACE(CONVERT(CHAR(11), @param, 106), ' ', '-')+' '+CONVERT(VARCHAR(5),@param,108)
end
else
begin
select @result = cast(@param as nvarchar(100))
end
return @result
/*
BaseType:
bigint
binary
char
date
datetime
datetime2
datetimeoffset
decimal
float
int
money
nchar
numeric
nvarchar
real
smalldatetime
smallint
smallmoney
time
tinyint
uniqueidentifier
varbinary
varchar
*/
end;
create function dbo.FormatString(
@format nvarchar(4000)
,@param1 sql_variant = null
,@param2 sql_variant = null
,@param3 sql_variant = null
,@param4 sql_variant = null
,@param5 sql_variant = null
)
returns nvarchar(4000)
begin
/*
Tejasvi Hegde, 29-April-2017
select dbo.FormatString('some string value %s some int %s date %s','"abcd"',100,cast(getdate() as date),DEFAULT,DEFAULT)
select dbo.FormatString('some string value %s some int %s date time %s','"abcd"',100,getdate(),DEFAULT,DEFAULT)
*/
declare @result nvarchar(4000)
select @param1 = dbo.formatValue(@param1)
,@param2 = dbo.formatValue(@param2)
,@param3 = dbo.formatValue(@param3)
,@param4 = dbo.formatValue(@param4)
,@param5 = dbo.formatValue(@param5)
select @param2 = cast(@param2 as nvarchar)
EXEC xp_sprintf @result OUTPUT,@format , @param1, @param2, @param3, @param4, @param5
return @result
end;
Folgendes habe ich bei meinen Experimenten mit dem eingebauten Gerät gefunden
FORMATMESSAGE () Funktion
sp_addmessage @msgnum=50001,@severity=1,@msgText='Hello %s you are #%d',@replace='replace'
SELECT FORMATMESSAGE(50001, 'Table1', 5)
Wenn Sie sp_addmessage aufrufen, wird Ihre Nachrichtenvorlage in der Systemtabelle master.dbo.sysmessages gespeichert (überprüft auf SQLServer 2000).
Sie müssen das Hinzufügen und Entfernen von Vorlagenzeichenfolgen aus der Tabelle selbst verwalten. Dies ist umständlich, wenn Sie nur eine kurze Nachricht an den Ergebnisbildschirm ausgeben möchten.
Die von Kathik DV bereitgestellte Lösung sieht interessant aus, funktioniert aber nicht mit SQL Server 2000, daher habe ich sie ein wenig geändert, und diese Version sollte mit allen Versionen von SQL Server funktionieren:
IF OBJECT_ID( N'[dbo].[FormatString]', 'FN' ) IS NOT NULL
DROP FUNCTION [dbo].[FormatString]
GO
/***************************************************
Object Name : FormatString
Purpose : Returns the formatted string.
Original Author : Karthik D V http://stringformat-in-sql.blogspot.com/
Sample Call:
SELECT dbo.FormatString ( N'Format {0} {1} {2} {0}', N'1,2,3' )
*******************************************/
CREATE FUNCTION [dbo].[FormatString](
@Format NVARCHAR(4000) ,
@Parameters NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
--DECLARE @Format NVARCHAR(4000), @Parameters NVARCHAR(4000) select @format='{0}{1}', @Parameters='hello,world'
DECLARE @Message NVARCHAR(400), @Delimiter CHAR(1)
DECLARE @ParamTable TABLE ( ID INT IDENTITY(0,1), Parameter VARCHAR(1000) )
Declare @startPos int, @endPos int
SELECT @Message = @Format, @Delimiter = ','
--handle first parameter
set @endPos=CHARINDEX(@Delimiter,@Parameters)
if (@endPos=0 and @Parameters is not null) --there is only one parameter
insert into @ParamTable (Parameter) values(@Parameters)
else begin
insert into @ParamTable (Parameter) select substring(@Parameters,0,@endPos)
end
while @endPos>0
Begin
--insert a row for each parameter in the
set @startPos = @endPos + LEN(@Delimiter)
set @endPos = CHARINDEX(@Delimiter,@Parameters, @startPos)
if (@endPos>0)
insert into @ParamTable (Parameter) select substring(@Parameters,@startPos,@endPos)
else
insert into @ParamTable (Parameter) select substring(@Parameters,@startPos,4000)
End
UPDATE @ParamTable SET @Message = REPLACE ( @Message, '{'+CONVERT(VARCHAR,ID) + '}', Parameter )
RETURN @Message
END
Go
grant execute,references on dbo.formatString to public
Verwendung:
print dbo.formatString('hello {0}... you are {1}','world,good')
--result: hello world... you are good
Im Moment existiert dies nicht wirklich (obwohl Sie natürlich Ihre eigenen schreiben können). Es gibt einen offenen Verbindungsfehler: https://connect.microsoft.com/SQLServer/Feedback/Details/3130221 , der zum jetzigen Zeitpunkt nur 1 Stimme hat.
Tatsächlich gibt es keine integrierte Funktion, die der Zeichenfolge ähnelt. Die Formatfunktion von .NET ist in SQL Server verfügbar.
Es gibt eine Funktion FORMATMESSAGE () in SQL Server, die jedoch die Funktion printf () von C nachahmt, nicht string.Format von .NET.
SELECT FORMATMESSAGE('This is the %s and this is the %s.', 'first variable', 'second variable') AS Result
Nicht genau, aber ich würde einige der Artikel über String-Handling (unter anderem) von "Phil Factor" (geddit?) Auf Simple Talk lesen.