programing

SQL Server에 후행 공백을 포함하지 않는 LEN 함수

telecom 2023. 6. 4. 10:17
반응형

SQL Server에 후행 공백을 포함하지 않는 LEN 함수

SQL Server 2005에는 다음과 같은 테스트 테이블이 있습니다.

CREATE TABLE [dbo].[TestTable]
(
 [ID] [int] NOT NULL,
 [TestField] [varchar](100) NOT NULL
) 

다음이 포함됨:

INSERT INTO TestTable (ID, TestField) VALUES (1, 'A value');   -- Len = 7
INSERT INTO TestTable (ID, TestField) VALUES (2, 'Another value      '); -- Len = 13 + 6 spaces

SQL Server LEN() 함수를 사용하여 TestField의 길이를 찾으려고 하면 뒤에 오는 공백이 계산되지 않습니다. 예:

-- Note: Also results the grid view of TestField do not show trailing spaces (SQL Server 2005).
SELECT 
 ID, 
 TestField, 
 LEN(TestField) As LenOfTestField, -- Does not include trailing spaces
FROM 
 TestTable

길이 결과에 후행 공백을 포함하려면 어떻게 해야 합니까?

이것은 MSDN(http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx, )에서 Microsoft에 의해 명확하게 문서화되어 있으며 LEN은 "뒤에 공백을 제외하고 지정된 문자열 식의 문자 수를 표시한다"고 명시되어 있습니다.그러나 경계하지 않으면 놓치기 쉬운 세부 사항입니다.

대신 "표현식을 나타내는 데 사용된 바이트 수를 나타내는" DATALENGTH 함수(http://msdn.microsoft.com/en-us/library/ms173486(SQL.90).aspx 참조)를 사용해야 합니다.

예:

SELECT 
    ID, 
    TestField, 
    LEN(TestField) As LenOfTestField,           -- Does not include trailing spaces
    DATALENGTH(TestField) As DataLengthOfTestField      -- Shows the true length of data, including trailing spaces.
FROM 
    TestTable

다음 방법을 사용할 수 있습니다.

LEN(Str + 'x') - 1

다음 방법을 사용합니다.

LEN(REPLACE(TestField, ' ', '.'))

저는 이것이 다른 데이터 유형에서 작동하기 때문에 DATALLength보다 이것을 더 선호하고, 문자열이 이미 최대 길이에 있는 에지 케이스에 대해 걱정할 필요가 없기 때문에 끝에 문자를 추가하는 것보다 더 선호합니다.

참고: 대용량 데이터 세트를 사용하기 전에 성능을 테스트합니다. 2M 행에 대해 테스트했을 뿐이며 REPLACE를 사용하지 않은 LEN보다 느리지는 않았습니다.

"길이 결과에 후행 공백을 포함하려면 어떻게 해야 합니까?"

여기에 나열된 이 놀랍도록 간단한 문제에 대한 거의 모든 해결 방법에 결함이 있거나 비효율적이기 때문에 SQL Server 향상 요청/버그 보고서를 제출할 사람이 있습니다.이는 SQL Server 2012에서 여전히 사실로 나타납니다.자동 트리밍 기능은 ANSI/ISO SQL-92에서 비롯될 수 있지만 일부 구멍(또는 구멍 수를 세지 않음)이 있는 것 같습니다.

여기서 "LEN이 후행 공백을 카운트하도록 설정 추가"를 투표하십시오.

https://feedback.azure.com/forums/908035-sql-server/suggestions/34673914-add-setting-so-len-counts-trailing-whitespace

수명 만료 연결 링크: https://connect.microsoft.com/SQLServer/feedback/details/801381

상위 투표된 두 개의 답변에 문제가 있습니다.을 답.DATALENGTH프로그래머 오류가 발생하기 쉽습니다.의 결과DATALENGTH다음에 대해 2로 나누어야 합니다.NVARCHAR유형, 그러나 해당되지 않음VARCHAR유형.는 자신이 지식이 하며, 그 형유를 . 이를 위해서는 길이를 얻는 유형에 대한 지식이 필요하며, 해당 유형이 변경되면 사용한 위치를 부지런히 변경해야 합니다.DATALENGTH.

가장 많이 투표된 답변(이 문제가 나를 괴롭힐 때까지 내가 선호하는 방법이었음을 인정함)에도 문제가 있습니다.길이를 받는 것이 유형인 경우NVARCHAR(4000)실제로 4000자의 문자열이 포함되어 있습니다. SQL은 결과를 암시적으로 캐스트하지 않고 추가된 문자를 무시합니다.NVARCHAR(MAX)최종 결과 길이가 잘못되었습니다.VARCHAR(8000)에서도 동일한 현상이 발생합니다.

내가 찾은 것은 오래된 것과 거의 같은 속도로 작동합니다.LEN보다 .LEN(@s + 'x') - 1문자열의 , 과 같이 .

DATALENGTH(@s) / DATALENGTH(LEFT(LEFT(@s, 1) + 'x', 1))

데이터 길이를 얻은 다음 문자열에서 단일 문자의 데이터 길이로 나눕니다.'x'의 부록은 문자열이 비어 있는 경우(이 경우 0으로 나눗셈을 제공함)를 포함합니다.은 효있습과까니가은 이것?▁whether 까니습?@s이라VARCHAR또는NVARCHARLEFT문자열이 클 때 추가 셰이핑하기 전에 1자입니다.그러나 이것의 문제는 대리 쌍을 포함하는 문자열에서 올바르게 작동하지 않는다는 것입니다.

수락된 답변에 대한 코멘트에 언급된 다른 방법은 다음과 같습니다.REPLACE(@s,' ','x')이 기술은 정답을 제공하지만 문자열이 클 때 다른 기술보다 몇 배 느립니다.

사용하는 모든 기술에서 대리 쌍에 의해 도입된 문제를 고려할 때DATALENGTH제가 알고 있는 정답을 제시하는 가장 안전한 방법은 다음과 같습니다.

LEN(CONVERT(NVARCHAR(MAX), @s) + 'x') - 1

▁the보다 빠릅니다.REPLACE기술, 그리고 더 긴 줄로 훨씬 더 빠릅니다.으로 이 은 기적으이기은술로본입니다.LEN(@s + 'x') - 1그러나 문자열의 길이가 4000(nvarchar) 또는 8000(varchar)인 에지 대소문자에 대한 보호를 통해 이에 대한 정답이 제공됩니다.또한 대리 쌍이 있는 문자열을 올바르게 처리해야 합니다.

LEN은 기본적으로 후행 공백을 잘라내기 때문에 앞으로 이동할 때 이 작업이 수행되었습니다.

(LEN(REVERSE(시험장))

그래서 만약 당신이 원한다면, 당신은 말할 수 있습니다.

SELECT
t.TestField,
LEN(REVERSE(t.TestField)) AS [Reverse],
LEN(t.TestField) AS [Count]
FROM TestTable t
WHERE LEN(REVERSE(t.TestField)) <> LEN(t.TestField)

물론 이것을 선행 공간에 사용하지 마십시오.

또한 데이터가 실제로 후행 공백으로 저장되었는지 확인해야 합니다.ANSI 패딩이 OFF(기본값이 아님)인 경우:

막대형 열에 삽입된 문자 값의 후행 공백이 잘립니다.

이것은 문자당 최대 길이 및 가변 바이트 수 문제를 처리하는 최고의 알고리즘입니다.

ISNULL(LEN(STUFF(@Input, 1, 1, '') + '.'), 0)

은 이은다변형다니입의음의 입니다.LEN(@Input + '.') - 1을 사용함으로써.STUFF 1첫을 문 제 를 거 기 위 하 문 수 해 최 없 습 니 다 필 가 요 번 않 하 째 초 뺄 록 도 길 고 과 하 지 이 를 대 자 열 이 자 된 정 ▁1 ▁the ▁to ▁need ▁to ▁doesn ▁subtract ▁ensure ▁remove ▁remove 다 ▁the ▁and 니 ▁that ▁character 없 습 ▁string ▁length ▁we

ISNULL(..., 0)는 @Input ''를@Input = ''를되었습니다.STUFFNULL.

는 @ 때 @Input NULL과 하지 않을 때 .LEN(NULL)어느 쪽이 돌아옵니까?NULL하다면 이 할 수 .

은 다은다음사결다니과입용을 사용한 입니다.LEN(@Input),LEN(@Input + '.') - 1,LEN(REPLACE(@Input, ' ', '.'))의 그상이STUFF, 샘사의 합니다.@Input = CAST(' S' + SPACE(3998) AS NVARCHAR(4000))1, 이상 반복 1,000회 이상

알고리즘. 데이터 길이 예상 결과 결과
8000 4000 2 14
+DOT-1 8000 4000 1 13
교체하다 8000 4000 4000 514
스터프+도트 8000 4000 4000 0

이 경우에는STUFF알고리즘이 실제로 더 빠릅니다.LEN()!

내부적으로 SQL이 마지막 문자를 보고 공백이 아니라면 계산을 최적화한다고 가정할 수 있습니다. 하지만 좋은 결과네요?

문자열이 작다는 것을 알지 못하는 한 REPLACE 옵션을 사용하지 마십시오. 매우 비효율적입니다.

문자열 연결을 원하지 않는 경우 문자열의 길이 필드를 반환하는 CLR 함수를 정의해야 합니다.사용합니다LEN('x' + @string + 'x') - 2내 프로덕션 사용 사례에서.

만약 당신이 그것을 싫어한다면,DATALENGTH대한 우려 ?:n/varchar 문다어떻까니습은음해제인로?까▁because니어?

select DATALENGTH(@var)/isnull(nullif(DATALENGTH(left(@var,1)),0),1)

그것은 정당한 것입니다.

select DATALENGTH(@var)/DATALENGTH(left(@var,1))

0으로 나누기 보호로 감싸여 있습니다.

단일 문자의 데이터 길이로 나누면 길이가 정규화됩니다.

(물론, 그것이 우려된다면 여전히 대리 쌍에 대한 문제가 있습니다.)

SELECT DATA Length('string') 사용

언급URL : https://stackoverflow.com/questions/2025585/len-function-not-including-trailing-spaces-in-sql-server

반응형