我正在寻找T-SQL中的内置函数/扩展函数,用于字符串操作,类似于.NET中的String.Format
方法。
答案 0 :(得分:60)
如果您使用的是SQL Server 2012及更高版本,则可以使用FORMATMESSAGE
。例如
DECLARE @s NVARCHAR(50) = 'World';
DECLARE @d INT = 123;
SELECT FORMATMESSAGE('Hello %s, %d', @s, @d)
-- RETURNS 'Hello World, 123'
来自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');
注意:
FORMATMESSAGE
会出现(无害)错误答案 1 :(得分:53)
看看xp_sprintf。以下示例。
DECLARE @ret_string varchar (255)
EXEC xp_sprintf @ret_string OUTPUT,
'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2'
PRINT @ret_string
结果如下所示:
INSERT INTO table1 VALUES (1, 2)
刚刚发现字符串的最大大小(255个字符限制)的问题,所以你可以使用alternative function:
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
要获得与上述相同的结果,请按以下方式调用该函数:
print dbo.fnSprintf('INSERT INTO %s VALUES (%s, %s)', 'table1,1,2', default)
答案 2 :(得分:14)
我创建了一个用户定义的函数来模仿string.format功能。 你可以使用它。
答案 3 :(得分:4)
有一种方法,但它有其局限性。您可以使用FORMATMESSAGE()
功能。它允许您使用类似于C中的printf()
函数的格式来格式化字符串。
但是,最大的限制是它只能用于sys.messages表中的消息。这是一篇关于它的文章:microsoft_library_ms186788
遗憾的是,没有更简单的方法可以做到这一点,因为有时你想在数据库中格式化字符串/ varchar。希望您只是希望以标准方式格式化字符串,并且可以使用sys.messages
表。
巧合的是,你也可以使用RAISERROR()
函数,严重程度非常低,raiseerror的文档甚至提到这样做,但结果只打印出来。因此,你无法对结果值做任何事情(根据我的理解)。
答案 4 :(得分:3)
原始t-sql仅限于CHARINDEX(),PATINDEX(),REPLACE()和SUBSTRING(),用于字符串操作。但是使用sql server 2005及更高版本,你可以设置在.Net中运行的用户定义函数,这意味着设置一个string.format()UDF不应该太难。
答案 5 :(得分:2)
还有一个想法。
虽然这不是一个通用的解决方案 - 它很简单,但至少对我来说很有效:)
对于一个占位符{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
对于两个占位符{0}和{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
对于三个占位符{0},{1}和{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
依旧......
这种方法允许我们在SELECT语句中使用这些函数,并使用nvarchar,number,bit和datetime数据类型的参数。
例如:
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);
答案 6 :(得分:1)
我认为在计算结束位置时会有小的修正。
这是正确的功能
**>>**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
答案 7 :(得分:1)
这是我的版本。可以扩展以容纳更多数量的参数,并可以根据类型扩展格式。目前只有日期和日期时间类型被格式化。
示例:
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)
输出:
some string "abcd" some int 100 date 29-Apr-2017
some string "abcd" some int 100 date time 29-Apr-2017 19:40
功能:
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;
答案 8 :(得分:0)
这是我在使用内置
的实验中发现的内容FORMATMESSAGE()函数
sp_addmessage @msgnum=50001,@severity=1,@msgText='Hello %s you are #%d',@replace='replace'
SELECT FORMATMESSAGE(50001, 'Table1', 5)
当您调用sp_addmessage时,您的消息模板将存储到系统表master.dbo.sysmessages中(在SQLServer 2000上验证)。
您必须自己管理表格中的模板字符串的添加和删除,如果您真正想要的是向结果屏幕输出快速消息,那就太尴尬了。
Kathik DV提供的解决方案看起来很有趣但不适用于SQL Server 2000,因此我对其进行了一些修改,此版本适用于所有版本的SQL Server:
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
用法:
print dbo.formatString('hello {0}... you are {1}','world,good')
--result: hello world... you are good
答案 9 :(得分:0)
目前这并不存在(虽然你当然可以写自己的)。它有一个开放的连接错误:https://connect.microsoft.com/SQLServer/Feedback/Details/3130221,在撰写本文时只有1票。
答案 10 :(得分:0)
实际上没有类似于string的内置函数..NET的Format函数在SQL Server中可用。
SQL Server中有一个函数 FORMATMESSAGE(),但它模仿了C的printf()函数而不是string.NET的Format函数。
SELECT FORMATMESSAGE('This is the %s and this is the %s.', 'first variable', 'second variable') AS Result
答案 11 :(得分:-1)
不完全是这样,但我会在Simple Talk上通过“Phil Factor”(geddit?)查看一些articles字符串处理(以及其他内容)。
答案 12 :(得分:-3)