最有效的T-SQL的方式来垫在一个varchar留下一定的长度?(Most efficient T-

2019-06-17 22:54发布

相比于说:

REPLICATE(@padchar, @len - LEN(@str)) + @str

Answer 1:

这是一个简单的低效率使用SQL的,不管你怎么做。

也许像

right('XXXXXXXXXXXX'+ rtrim(@str), @n)

其中X是填充字符和@n是得到的字符串中的字符数(假设你需要填充,因为你是在处理一个固定长度)。

但正如我说你应该避免在你的数据库做这个。



Answer 2:

我知道这本来是在2008年回问,但也有与SQL Server 2012中引入的一些新功能的格式化功能简化填充剩下的零很好。 这也将会为你执行的转换:

declare @n as int = 2
select FORMAT(@n, 'd10') as padWithZeros

更新:

我想测试该格式的实际效率函数自己。 我很惊讶地发现,相比于从原来的答复效率不是很好AlexCuse 。 虽然我找到格式化功能清洁剂,它不是在执行时间方面非常有效。 我使用的帐簿桌有64000条记录。 荣誉对马丁·史密斯的指出了执行时间效率。

SET STATISTICS TIME ON
select FORMAT(N, 'd10') as padWithZeros from Tally
SET STATISTICS TIME OFF

SQL Server的执行时间:CPU时间= 2157毫秒,经过时间= 2696毫秒。

SET STATISTICS TIME ON
select right('0000000000'+ rtrim(cast(N as varchar(5))), 10) from Tally
SET STATISTICS TIME OFF

SQL Server的执行时间:

CPU时间= 31毫秒,经过时间= 235毫秒。



Answer 3:

几个人给的这个版本:

right('XXXXXXXXXXXX'+ @str, @n)

小心因为它会截断实际数据如果大于n。



Answer 4:

@padstr = REPLICATE(@padchar, @len) -- this can be cached, done only once

SELECT RIGHT(@padstr + @str, @len)


Answer 5:

也许一个过来杀掉我已经这些UDF垫左右

ALTER   Function [dbo].[fsPadLeft](@var varchar(200),@padChar char(1)='0',@len int)
returns varchar(300)
as
Begin

return replicate(@PadChar,@len-Len(@var))+@var

end

和向右

ALTER function [dbo].[fsPadRight](@var varchar(200),@padchar char(1)='0', @len int) returns varchar(201) as
Begin

--select @padChar=' ',@len=200,@var='hello'


return  @var+replicate(@PadChar,@len-Len(@var))
end


Answer 6:

我不知道,你给的方法实在是低效率的,但替代的方式,只要它不必须是在长度或填充字符灵活,将是(假设你需要填充它与“ 0" 到10个字符:

DECLARE
   @pad_characters VARCHAR(10)

SET @pad_characters = '0000000000'

SELECT RIGHT(@pad_characters + @str, 10)


Answer 7:

可能是矫枉过正,我经常使用这个UDF:

CREATE FUNCTION [dbo].[f_pad_before](@string VARCHAR(255), @desired_length INTEGER, @pad_character CHAR(1))
RETURNS VARCHAR(255) AS  
BEGIN

-- Prefix the required number of spaces to bulk up the string and then replace the spaces with the desired character
 RETURN ltrim(rtrim(
        CASE
          WHEN LEN(@string) < @desired_length
            THEN REPLACE(SPACE(@desired_length - LEN(@string)), ' ', @pad_character) + @string
          ELSE @string
        END
        ))
END

所以,你可以做这样的事情:

select dbo.f_pad_before('aaa', 10, '_')


Answer 8:

我喜欢vnRocks的解决方案,这是一个UDF的形式

create function PadLeft(
      @String varchar(8000)
     ,@NumChars int
     ,@PadChar char(1) = ' ')
returns varchar(8000)
as
begin
    return stuff(@String, 1, 0, replicate(@PadChar, @NumChars - len(@String)))
end


Answer 9:

这是一个简单的方法来垫左:

REPLACE(STR(FACT_HEAD.FACT_NO, x, 0), ' ', y)

其中x是垫数量, y是填充字符。

样品:

REPLACE(STR(FACT_HEAD.FACT_NO, 3, 0), ' ', 0)


Answer 10:

select right(replicate(@padchar, @len) + @str, @len)


Answer 11:

在SQL Server 2005及更高版本,你可以创建一个CLR函数来做到这一点。



Answer 12:

这个怎么样:

replace((space(3 - len(MyField))

图3是的数目zeros到垫



Answer 13:

我希望这可以帮助别人。

STUFF ( character_expression , start , length ,character_expression )

select stuff(@str, 1, 0, replicate('0', @n - len(@str)))


Answer 14:

我用这一个。 它可以让你确定你想要得到的结果是长度以及默认的填充字符如果不提供一个。 当然,你可以自定义输入和输出的最大值无论你正在运行到的长度。

/*===============================================================
 Author         : Joey Morgan
 Create date    : November 1, 2012
 Description    : Pads the string @MyStr with the character in 
                : @PadChar so all results have the same length
 ================================================================*/
 CREATE FUNCTION [dbo].[svfn_AMS_PAD_STRING]
        (
         @MyStr VARCHAR(25),
         @LENGTH INT,
         @PadChar CHAR(1) = NULL
        )
RETURNS VARCHAR(25)
 AS 
      BEGIN
        SET @PadChar = ISNULL(@PadChar, '0');
        DECLARE @Result VARCHAR(25);
        SELECT
            @Result = RIGHT(SUBSTRING(REPLICATE('0', @LENGTH), 1,
                                      (@LENGTH + 1) - LEN(RTRIM(@MyStr)))
                            + RTRIM(@MyStr), @LENGTH)

        RETURN @Result

      END

你的旅费可能会改变。 :-)

乔伊摩根
程序员/分析员校长我
康典医疗业务部



Answer 15:

这里是我的解决方案,避免了截短的字符串,并使用纯醇” SQL。 由于@AlexCuse,@Kevin@Sklivvz,其解决方案是该代码的基础。

 --[@charToPadStringWith] is the character you want to pad the string with.
declare @charToPadStringWith char(1) = 'X';

-- Generate a table of values to test with.
declare @stringValues table (RowId int IDENTITY(1,1) NOT NULL PRIMARY KEY, StringValue varchar(max) NULL);
insert into @stringValues (StringValue) values (null), (''), ('_'), ('A'), ('ABCDE'), ('1234567890');

-- Generate a table to store testing results in.
declare @testingResults table (RowId int IDENTITY(1,1) NOT NULL PRIMARY KEY, StringValue varchar(max) NULL, PaddedStringValue varchar(max) NULL);

-- Get the length of the longest string, then pad all strings based on that length.
declare @maxLengthOfPaddedString int = (select MAX(LEN(StringValue)) from @stringValues);
declare @longestStringValue varchar(max) = (select top(1) StringValue from @stringValues where LEN(StringValue) = @maxLengthOfPaddedString);
select [@longestStringValue]=@longestStringValue, [@maxLengthOfPaddedString]=@maxLengthOfPaddedString;

-- Loop through each of the test string values, apply padding to it, and store the results in [@testingResults].
while (1=1)
begin
    declare
        @stringValueRowId int,
        @stringValue varchar(max);

    -- Get the next row in the [@stringLengths] table.
    select top(1) @stringValueRowId = RowId, @stringValue = StringValue
    from @stringValues 
    where RowId > isnull(@stringValueRowId, 0) 
    order by RowId;

    if (@@ROWCOUNT = 0) 
        break;

    -- Here is where the padding magic happens.
    declare @paddedStringValue varchar(max) = RIGHT(REPLICATE(@charToPadStringWith, @maxLengthOfPaddedString) + @stringValue, @maxLengthOfPaddedString);

    -- Added to the list of results.
    insert into @testingResults (StringValue, PaddedStringValue) values (@stringValue, @paddedStringValue);
end

-- Get all of the testing results.
select * from @testingResults;


Answer 16:

我知道这并没有太多的谈话在这一点,但我运行的文件生成过程和它去慢得令人难以置信。 我一直在使用复制,看到这个装饰方法,想出去给它一个镜头。

你可以在我的代码看到两者之间的切换是除了新@padding变量(以及现在存在的限制)。 我跑在与执行时间相同的结果,这两个州的功能我的程序。 因此,至少在SQLServer2016,我没有看到其他的发现效率的任何差异。

不管怎么说,这是我的UDF是我几年前写的,加上今天的变化是一样一样的其他比它的左/右param选项和一些错误检查其他的。

CREATE FUNCTION PadStringTrim 
(
    @inputStr varchar(500), 
    @finalLength int, 
    @padChar varchar (1),
    @padSide varchar(1)
)
RETURNS VARCHAR(500)

AS BEGIN
    -- the point of this function is to avoid using replicate which is extremely slow in SQL Server
    -- to get away from this though we now have a limitation of how much padding we can add, so I've settled on a hundred character pad 
    DECLARE @padding VARCHAR (100) = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    SET @padding = REPLACE(@padding, 'X', @padChar)


    SET @inputStr = RTRIM(LTRIM(@inputStr))

    IF LEN(@inputStr) > @finalLength 
        RETURN '!ERROR!' -- can search for ! in the returned text 

    ELSE IF(@finalLength > LEN(@inputStr))
        IF @padSide = 'L'
            SET @inputStr = RIGHT(@padding + @inputStr, @finalLength)
            --SET @inputStr = REPLICATE(@padChar, @finalLength - LEN(@inputStr)) + @inputStr
        ELSE IF @padSide = 'R'
            SET @inputStr = LEFT(@inputStr + @padding, @finalLength)
            --SET @inputStr = @inputStr + REPLICATE(@padChar, @finalLength - LEN(@inputStr)) 



    -- if LEN(@inputStr) = @finalLength we just return it 
    RETURN @inputStr;
END

-- SELECT  dbo.PadStringTrim( tblAccounts.account, 20, '~' , 'R' ) from tblAccounts
-- SELECT  dbo.PadStringTrim( tblAccounts.account, 20, '~' , 'L' ) from tblAccounts


Answer 17:

为了提供数值四舍五入至小数点后两位,但用零向右填充如果需要的话,我有:

DECLARE @value = 20.1
SET @value = ROUND(@value,2) * 100
PRINT LEFT(CAST(@value AS VARCHAR(20)), LEN(@value)-2) + '.' + RIGHT(CAST(@value AS VARCHAR(20)),2)

如果任何人都可以想到的更合适的方法,这将不胜感激-上面似乎笨拙

:在这种情况下,我使用的SQL Server电子邮件中的HTML格式的报表,因此希望不涉及额外的工具来分析数据格式的信息。



Answer 18:

下面是我通常会垫一个varchar

WHILE Len(@String) < 8
BEGIN
    SELECT @String = '0' + @String
END


文章来源: Most efficient T-SQL way to pad a varchar on the left to a certain length?