답변:
방법에 관계없이 단순히 SQL을 비효율적으로 사용하는 것입니다.
아마도 같은
right('XXXXXXXXXXXX'+ rtrim(@str), @n)
여기서 X는 패딩 문자이고 @n은 결과 문자열의 문자 수입니다 (고정 길이를 처리하기 때문에 패딩이 필요하다고 가정).
그러나 내가 말했듯이 실제로는 데이터베이스 에서이 작업을 수행하지 않아야합니다.
RTRIM(@str)
그러나 후행 공백이 포함될 수 있으면 필요할 수 있습니다.
2008 년에 이것이 원래 요청되었지만 SQL Server 2012에 도입 된 몇 가지 새로운 기능이 있습니다. FORMAT 함수 는 왼쪽에 0으로 채워지는 패딩을 단순화합니다. 또한 당신을 위해 변환을 수행합니다 :
declare @n as int = 2
select FORMAT(@n, 'd10') as padWithZeros
최신 정보:
FORMAT 기능의 실제 효율성을 직접 테스트하고 싶었습니다. AlexCuse 의 원래 답변과 비교할 때 효율성이 좋지 않다는 사실에 놀랐습니다 . FORMAT 기능 클리너를 찾았지만 실행 시간 측면에서 그리 효율적이지 않습니다. 사용한 Tally 테이블에는 64,000 개의 레코드가 있습니다. 했네 마틴 스미스 실행 시간의 효율성을 지적.
SET STATISTICS TIME ON
select FORMAT(N, 'd10') as padWithZeros from Tally
SET STATISTICS TIME OFF
SQL Server 실행 시간 : CPU 시간 = 2157ms, 경과 시간 = 2696ms
SET STATISTICS TIME ON
select right('0000000000'+ rtrim(cast(N as varchar(5))), 10) from Tally
SET STATISTICS TIME OFF
SQL Server 실행 시간 :
CPU 시간 = 31ms, 경과 시간 = 235ms
어쩌면 오버 킬로이 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
아마 과잉일지도 모르지만, 나는 종종이 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, '_')
이것은 왼쪽을 채우는 간단한 방법입니다.
REPLACE(STR(FACT_HEAD.FACT_NO, x, 0), ' ', y)
x
패드 번호는 어디에 y
있고 패드 문자입니다.
견본:
REPLACE(STR(FACT_HEAD.FACT_NO, 3, 0), ' ', 0)
1
된다 001
.
나는 이것을 사용합니다. 기본 패딩 문자 (제공되지 않은 경우)뿐만 아니라 결과 길이를 결정할 수 있습니다. 물론 최대 길이에 상관없이 입력 및 출력 길이를 사용자 정의 할 수 있습니다.
/*===============================================================
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
귀하의 마일리지가 다를 수 있습니다. :-)
Joey Morgan
프로그래머 / 분석가 교장 I
WellPoint Medicaid 사업부
다음은 잘린 문자열을 피하고 일반 ol '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;
나는 이것이 현재 대화에 많은 것을 추가하지는 않지만 파일 생성 절차를 실행하고 있으며 매우 느리게 진행되고 있음을 알고 있습니다. 나는 복제를 사용하고 있었고이 트림 방법을 보았고 나는 그것을 줄 것이라고 생각했습니다.
내 코드에서 새로운 @padding 변수와 현재 존재하는 제한 외에도 두 가지 사이의 전환이있는 곳을 볼 수 있습니다. 실행 시간이 동일한 결과로 두 상태에서 함수로 내 프로 시저를 실행했습니다. 따라서 적어도 SQLServer2016에서는 다른 제품과 비교했을 때 효율성에 차이가 없습니다.
어쨌든, 여기에 내가 몇 년 전에 쓴 UDF와 오늘의 변경 사항이 LEFT / RIGHT 매개 변수 옵션과 일부 오류 검사가있는 것 이외의 다른 변경 사항과 거의 동일합니다.
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
lpad에 x 10 진수를 갖는 함수가 하나 있습니다 : CREATE FUNCTION [dbo]. [LPAD_DEC] (-함수에 대한 매개 변수를 여기에 @pad nvarchar (MAX), @string nvarchar (MAX), @length int, @dec int 추가 ) nvarchar (max)를 BEGIN으로 반환-여기서 반환 변수를 선언합니다. DECLARE @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
종료
소수점 이하 두 자리로 반올림하지만 필요한 경우 0으로 오른쪽 채워진 숫자 값을 제공하려면 다음이 있습니다.
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 형식으로 전자 메일로 보내므로 데이터를 구문 분석하는 추가 도구를 사용하지 않고 정보의 형식을 지정하려고합니다.