String.Format like functionality in T-SQL?

后端 未结 13 1886
滥情空心
滥情空心 2020-12-02 12:54

I\'m looking for a built-in function/extended function in T-SQL for string manipulation similar to the String.Format method in .NET.

相关标签:
13条回答
  • 2020-12-02 13:27

    I have created a user defined function to mimic the string.format functionality. You can use it.

    stringformat-in-sql

    0 讨论(0)
  • 2020-12-02 13:27

    here's what I found with my experiments using the built-in

    FORMATMESSAGE() function

    sp_addmessage @msgnum=50001,@severity=1,@msgText='Hello %s you are #%d',@replace='replace'
    SELECT FORMATMESSAGE(50001, 'Table1', 5)
    

    when you call up sp_addmessage, your message template gets stored into the system table master.dbo.sysmessages (verified on SQLServer 2000).

    You must manage addition and removal of template strings from the table yourself, which is awkward if all you really want is output a quick message to the results screen.

    The solution provided by Kathik DV, looks interesting but doesn't work with SQL Server 2000, so i altered it a bit, and this version should work with all versions of 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
    

    Usage:

    print dbo.formatString('hello {0}... you are {1}','world,good')
    --result: hello world... you are good
    
    0 讨论(0)
  • 2020-12-02 13:28

    this is bad approach. you should work with assembly dll's, in which will do the same for you with better performance.

    0 讨论(0)
  • 2020-12-02 13:30

    At the moment this doesn't really exist (although you can of course write your own). There is an open connect bug for it: https://connect.microsoft.com/SQLServer/Feedback/Details/3130221, which as of this writing has just 1 vote.

    0 讨论(0)
  • 2020-12-02 13:33

    take a look at xp_sprintf. example below.

    DECLARE @ret_string varchar (255)
    EXEC xp_sprintf @ret_string OUTPUT, 
        'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2'
    PRINT @ret_string
    

    Result looks like this:

    INSERT INTO table1 VALUES (1, 2)
    

    Just found an issue with the max size (255 char limit) of the string with this so there is an alternative function you can use:

    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
    

    To get the same result as above you call the function as follows:

    print dbo.fnSprintf('INSERT INTO %s VALUES (%s, %s)', 'table1,1,2', default)
    
    0 讨论(0)
  • 2020-12-02 13:37

    Here is my version. Can be extended to accommodate more number of parameters and can extend formatting based on type. Currently only date and datetime types are formatted.

    Example:

    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)
    

    Output:

    some string "abcd" some int 100 date 29-Apr-2017
    some string "abcd" some int 100 date time 29-Apr-2017 19:40
    

    Functions:

    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;
    
    0 讨论(0)
提交回复
热议问题