相比之下,说:
REPLICATE(@padchar, @len - LEN(@str)) + @str
相比之下,说:
REPLICATE(@padchar, @len - LEN(@str)) + @str
当前回答
select right(replicate(@padchar, @len) + @str, @len)
其他回答
我有一个函数lpad有x个小数 创建函数[dbo].[LPAD_DEC] ( ——在这里添加函数的参数 @pad nvarchar (MAX), @string nvarchar (MAX), @length int, @dec int ) 返回nvarchar (max) 作为 开始 ——在这里声明返回变量 声明@resp nvarchar(max)
IF LEN(@string)=@length
BEGIN
IF CHARINDEX('.',@string)>0
BEGIN
SELECT @resp = CASE SIGN(@string)
WHEN -1 THEN
-- Nros negativos grandes con decimales
concat('-',SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec)))
ELSE
-- Nros positivos grandes con decimales
concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(@string,@length,@dec)))
END
END
ELSE
BEGIN
SELECT @resp = CASE SIGN(@string)
WHEN -1 THEN
--Nros negativo grande sin decimales
concat('-',SUBSTRING(replicate(@pad,@length),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
ELSE
-- Nros positivos grandes con decimales
concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(@string,@length,@dec)))
END
END
END
ELSE
IF CHARINDEX('.',@string)>0
BEGIN
SELECT @resp =CASE SIGN(@string)
WHEN -1 THEN
-- Nros negativos con decimales
concat('-',SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec)))
ELSE
--Ntos positivos con decimales
concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec)))
END
END
ELSE
BEGIN
SELECT @resp = CASE SIGN(@string)
WHEN -1 THEN
-- Nros Negativos sin decimales
concat('-',SUBSTRING(replicate(@pad,@length-3),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
ELSE
-- Nros Positivos sin decimales
concat(SUBSTRING(replicate(@pad,@length),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
END
END
RETURN @resp
END
我知道这个问题最初是在2008年提出的,但是在SQL Server 2012中引入了一些新函数。FORMAT函数很好地简化了以零结尾的填充。它也会为你执行转换:
declare @n as int = 2
select FORMAT(@n, 'd10') as padWithZeros
更新:
我想亲自测试FORMAT函数的实际效率。我很惊讶地发现,与AlexCuse的原始答案相比,效率不是很好。虽然我发现FORMAT函数更简洁,但就执行时间而言,它不是很高效。我使用的tallytable有64,000条记录。Martin Smith指出了执行时间效率。
SET STATISTICS TIME ON
select FORMAT(N, 'd10') as padWithZeros from Tally
SET STATISTICS TIME OFF
SQL Server执行次数: CPU时间= 2157 ms,运行时间= 2696 ms。
SET STATISTICS TIME ON
select right('0000000000'+ rtrim(cast(N as varchar(5))), 10) from Tally
SET STATISTICS TIME OFF
SQL Server执行次数:
CPU时间= 31 ms,运行时间= 235 ms。
@padstr = REPLICATE(@padchar, @len) -- this can be cached, done only once
SELECT RIGHT(@padstr + @str, @len)
我知道这在这一点上没有增加太多的对话,但我正在运行一个文件生成程序,它的速度非常慢。我一直在使用复制,看到了这种修剪方法,并认为我应该给它一个机会。
在我的代码中,你可以看到在这两个变量之间的切换是除了新的@padding变量(以及现在存在的限制)。我在两种状态下用函数运行我的过程,在执行时间内得到了相同的结果。因此,至少在SQLServer2016中,我没有看到其他发现的效率有任何差异。
无论如何,这是我的UDF,我写了几年前加上今天的变化,这是非常相同的,因为它有一个左/右参数选项和一些错误检查。
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
这是我的解决方案。我可以填充任何字符,它是快速的。选择简单。您可以更改可变大小以满足您的需要。
更新了一个参数来处理如果为空返回什么:null如果为空将返回null
CREATE OR ALTER FUNCTION code.fnConvert_PadLeft(
@in_str nvarchar(1024),
@pad_length int,
@pad_char nchar(1) = ' ',
@rtn_null NVARCHAR(1024) = '')
RETURNS NVARCHAR(1024)
AS
BEGIN
DECLARE @rtn NCHAR(1024) = ' '
RETURN RIGHT(REPLACE(@rtn,' ',@pad_char)+ISNULL(@in_str,@rtn_null), @pad_length)
END
GO
CREATE OR ALTER FUNCTION code.fnConvert_PadRight(
@in_str nvarchar(1024),
@pad_length int,
@pad_char nchar(1) = ' ',
@rtn_null NVARCHAR(1024) = '')
RETURNS NVARCHAR(1024)
AS
BEGIN
DECLARE @rtn NCHAR(1024) = ' '
RETURN LEFT(ISNULL(@in_str,@rtn_null)+REPLACE(@rtn,' ',@pad_char), @pad_length)
END
GO
-- Example
SET STATISTICS time ON
SELECT code.fnConvert_PadLeft('88',10,'0',''),
code.fnConvert_PadLeft(null,10,'0',''),
code.fnConvert_PadLeft(null,10,'0',null),
code.fnConvert_PadRight('88',10,'0',''),
code.fnConvert_PadRight(null,10,'0',''),
code.fnConvert_PadRight(null,10,'0',NULL)
0000000088 0000000000 NULL 8800000000 0000000000 NULL