最有效的T-SQL方法将左侧的varchar填充到一定的长度?
相比之下说:
REPLICATE(@padchar, @len - LEN(@str)) + @str
这只是SQL的低效使用,不pipe你怎么做。
也许类似
right('XXXXXXXXXXXX'+ rtrim(@str), @n)
其中X是您的填充字符,@n是结果string中的字符数(假设您需要填充因为您处理的是固定长度)。
但正如我所说,你应该避免在数据库中这样做。
我知道这是最初在2008年提出的,但是SQL Server 2012引入了一些新function.FORMAT函数很好地简化了填充左边的填充。 它也将为您执行转换:
declare @n as int = 2 select FORMAT(@n, 'd10') as padWithZeros
更新:
我想自己testingFORMAT函数的实际效率。 与来自AlexCuse的原始答案相比,我很惊讶地发现效率不是很好。 尽pipe我发现FORMAT函数更清晰,但在执行时间方面效率并不高。 我使用的Tally表有64,000条logging。 向Martin Smith表示指出执行时间的效率。
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毫秒。
有几个人给出了这样的版本:
right('XXXXXXXXXXXX'+ @str, @n)
要小心,因为它会截断你的实际数据,如果它比n长。
@padstr = REPLICATE(@padchar, @len) -- this can be cached, done only once SELECT RIGHT(@padstr + @str, @len)
也许过度杀死我有这些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
我不确定你提供的方法是否真的效率低下,但是一个替代的方法,只要它不需要在长度或填充字符方面是灵活的,就可以(假设你想用“ 0“到10个字符:
DECLARE @pad_characters VARCHAR(10) SET @pad_characters = '0000000000' SELECT RIGHT(@pad_characters + @str, 10)
在SQL Server 2005和更高版本中,您可以创build一个CLR函数来执行此操作。
可能矫枉过正,我经常使用这个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, '_')
我喜欢vnRocks解决scheme,这里是udf的forms
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
这是一个简单的方法来填充左侧:
REPLACE(STR(FACT_HEAD.FACT_NO, x, 0), ' ', y)
其中x
是垫号, y
是垫字符。
样品:
REPLACE(STR(FACT_HEAD.FACT_NO, 3, 0), ' ', 0)
select right(replicate(@padchar, @len) + @str, @len)
我希望这可以帮助别人。
STUFF(character_expression,start,length,character_expression)
(@str,1,0,replicate('0',@n – len(@str)))
这个怎么样:
replace((space(3 - len(MyField))
3是要填充的zeros
的数量
提供四舍五入到小数点后两位的数字值,但是如果需要的话用右填充零,我有:
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格式发送报告,因此希望格式化信息而不涉及额外的工具来parsing数据。
我用这个。 它允许你确定你想要的结果的长度,以及默认的填充字符(如果没有提供)。 当然,您可以自定义input和输出的长度,以适应您正在运行的任何最大值。
/*=============================================================== 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
你的旅费可能会改变。 🙂
乔伊摩根
程序员/分析师负责人
WellPoint医疗补助事业部
这是我的解决scheme,它可以避免截断string,并使用普通的SQL。 感谢@AlexCuse , @Kevin和@Sklivvz ,他们的解决scheme是这个代码的基础。
--[@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;
这里是我通常会填充一个varchar
WHILE Len(@String) < 8 BEGIN SELECT @String = '0' + @String END