像T-SQL中的功能一样的String.Format吗?

时间:2020-03-06 14:59:48  来源:igfitidea点击:

我正在寻找T-SQL中的内置函数/扩展函数来进行类似于.NET中的String.Format方法的字符串操作。

解决方案

原始t-sql仅限于CHARINDEX(),PATINDEX(),REPLACE()和SUBSTRING()进行字符串操作。但是,在sql server 2005及更高版本中,我们可以设置在.Net中运行的用户定义函数,这意味着设置string.format()UDF应该不会太困难。

不完全是,但是我会在Simple Talk上查看" Phil Factor"(geddit?)中有关字符串处理的文章(以及其他内容)。

有一种方法,但是它有其局限性。我们可以使用FORMATMESSAGE()函数。它允许我们使用类似于C语言中的printf()函数的格式来格式化字符串。

但是,最大的限制是它仅适用于sys.messages表中的消息。这是关于它的文章:microsoft_library_ms186788

遗憾的是,没有一种更简单的方法可以执行此操作,因为有时我们需要在数据库中格式化字符串/ varchar。希望我们只是希望以一种标准的方式格式化字符串,并且可以使用sys.messages表。

巧合的是,我们也可以使用严重性非常低的RAISERROR()函数,raiseerror的文档甚至提到这样做,但是只打印结果。因此,根据结果(根据我的理解),我们将无法做任何事情。

祝你好运!

看一下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个字符限制)存在问题,因此我们可以使用替代功能:

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)

我创建了一个用户定义的函数来模仿string.format功能。
我们可以使用它。

SQL中的字符串格式

这是我使用内置的实验发现的结果

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