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


109

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

길이 결과에 후행 공백을 어떻게 포함합니까?


1
여기서 진짜 해결책은 마이크로 소프트가 깨진 소프트웨어를 고치는 것이라고 생각합니다. 여기에 투표 : feedback.azure.com/forums/908035-sql-server/suggestions/...
QA 단체

답변:


125

이것은 Microsoft가 MSDN의 http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx 에서 명확하게 문서화했으며 , 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

52
참고 : DATALENGTH테스트중인 표현식이 와이드 문자 유형 (유니 코드, nchar, nvarchar 또는 ntext) 인 경우 결과가 characters가 아니라 bytes 이므로 결과를 2로 나누어야합니다 .
devstuff

7
또한 varchar등을 위해 이것은 데이터 정렬에 따라 달라질 수 있으며 2로 직접 나누는 것도 신뢰할 수 없습니다. 참조 여기에 예를
마틴 스미스에게

18
나는 LEN(REPLACE(expr, ' ', '_')). 특수 유니 코드 제어 문자를 포함하는 varcharnvarchar및 문자열 과 함께 작동해야 합니다.
Olivier Jacot-Descombes 2014

6
-1 DATALENGTH()은 문자 대신 바이트를 계산하고 VARCHAR/ 에서 동일한 문자열을 나타낼 때 중요하므로 문자를 계산하는 다른 방법으로 간주해서는 안됩니다 NVARCHAR.
binki

5
SQL Server 2012부터 버전 100 데이터 정렬이 포함 된 유니 코드 열은 이제 서로 게이트 쌍을 지원합니다. 즉, 단일 문자가 최대 4 바이트를 사용할 수 있으므로 2로 나누기가 실패합니다. msdn을 참조하십시오 .
Frédéric

85

이 트릭을 사용할 수 있습니다.

LEN (Str + 'x')-1


15
더 나은 대안으로 우리를 계몽 해 주시겠습니까? Datalength는 확실하지 않습니다.
서지

15
일관성이없는 방법 (어떤 경우에는 결과를 2로 나누기도하고 때로는 그렇지 않은 경우도 있음)을 사용하는 것이 더 나은 옵션이라는 데 동의하지 않습니다. 그래도 내 방법으로 성능 저하가 거의 없을 수도 있습니다.
Serge 2013 년

5
@usr Serge의 방법이 최고입니다, IMHO. 간단하고 우아합니다. DATALENGTH는 복잡합니다. 단일 / 더블 바이트 유형 종속, 데이터 정렬 / 언어 종속 등
Mr. TA

10
이것은 지금까지 가장 훌륭하고 우아한 솔루션입니다. 나는 그것이 해킹처럼 느껴지는 지 아닌지 (코딩은 감정에 관한 것이 아님)별로 신경 쓰지 않는다. 나는이 솔루션이 부작용이 없다는 사실에 정말로 관심이있다. 데이터 유형 varchar / nvarchar를 변경할 수 있지만 여전히 작동합니다. 잘 했어.
Mike Keskinov 2014 년

5
이 부작용 때문에주의 할 점이 있습니다. nvarchar (4000) 유형의 변수로 작업하고 변수에 4000 자 문자열이 포함 된 경우 추가 된 문자가 무시되고 잘못된 결과 (후행 공백을 무시하는 SQL의 len에서 1을 뺀 값)가 표시됩니다. 빼기).
도끼 - SOverflow으로 수행

17

이 방법을 사용합니다.

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

이것은 다른 데이터 유형에서 작동하기 때문에 DATALENGTH보다 선호하고 문자열이 이미 최대 길이에있는 경우에 대해 걱정할 필요가 없기 때문에 끝에 문자를 추가하는 것보다 선호합니다.

참고 : 매우 큰 데이터 세트에 대해 사용하기 전에 성능을 테스트합니다. 2M 행에 대해 테스트했지만 REPLACE 없이는 LEN보다 느리지 않았습니다.


14

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

여기에있는이 놀랍도록 간단한 문제에 대해 나열된 거의 모든 해결 방법에 결함이 있거나 비효율적이기 때문에 누군가 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


2
datalength솔루션은 이제 UTF-16에서 서로 게이트 쌍을 지원하므로 SQL Server 2012부터는 더 나쁩니다. 즉, 문자가 최대 4 바이트를 사용할 수 있습니다. 실제로 lenANSI를 준수하기 위해 함수를 수정 하거나 최소한 후행 공백을 포함하여 문자를 계산하는 전용 함수를 제공 할 때입니다.
Frédéric

1
이를 위해 피드백 링크를 더 많이 사용해야합니다. 이 문제는 인터넷을 통해서만 검색 할 수 있다는 것은 당혹 스럽습니다. LEN () 함수가 연결 끊김의 원인이라고 생각하기 전에 내 코드에서 실수를했는지 알아 내려고 거의 2 시간을 보냈습니다.
Takophiliac 2019

나는 이것에 동의하지만 iqueryable 표현식이 빌드 될 때 공백이 포함되어 있는지 확인할 필요없이 EF와의 문자열 비교를 훨씬 쉽게 만들기 때문에 매개 변수가 공백을 제거하도록 허용해야합니다.
ganjeii

9

가장 많이 득표 한 두 답변에 문제가 있습니다. 권장하는 대답 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으로 나누기). 이 여부를 작동 @s하다 VARCHAR거나 NVARCHAR. 하기LEFT추가하기 전에 1 문자를 문자열이 클 때 얼마 동안 면도됩니다. 하지만 문제는 서로 게이트 쌍을 포함하는 문자열에서 올바르게 작동하지 않는다는 것입니다.

수락 된 답변에 대한 의견에서 REPLACE(@s,' ','x'). 이 기술은 정답을 제공하지만 문자열이 클 때 다른 기술보다 몇 배 느립니다.

를 사용하는 모든 기술에서 대리 쌍으로 인한 문제를 고려할 때 DATALENGTH내가 아는 정답을 제공하는 가장 안전한 방법은 다음과 같습니다.

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

이것은 REPLACE기술보다 빠르며 긴 문자열에서는 훨씬 빠릅니다. 기본적으로이 기술은 LEN(@s + 'x') - 1기술이지만 문자열의 길이가 4000 (nvarchar의 경우) 또는 8000 (varchar의 경우) 인 가장자리 케이스에 대한 보호 기능이있어 이에 대한 정답이 제공됩니다. 또한 서로 게이트 쌍이있는 문자열을 올바르게 처리해야합니다.


1
불행히도이 대답은 SQL Server 2012에서 서로 게이트 쌍을 포함하는 문자열에 대해 더 이상 작동하지 않습니다. 작업을 실행 N'x𤭢x' COLLATE Latin1_General_100_CI_AS_SC하면 4가 LEN제공되고 3이 제공됩니다.
Douglas

9
@Douglas-유용한 정보입니다. Microsoft가 후행 공백을 무시하지 않는 LEN 버전을 제공한다면.
도끼 - SOverflow으로 수행

5

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

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


3
이 설정은 더 이상 사용되지 않으므로 ANSI PADDING을 끄면 안된다고 생각합니다. 비표준 값으로 설정하면 많은 작은 문제가 발생합니다.
usr

4

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)

물론 선행 공백에는 사용하지 마십시오.


9
이제 후행 공백 대신 선행 공백을 자릅니다 . 같은 날, 다른 문제 :
반전 엔지니어

@DaveBoltman 내 제안은 여전히 ​​더 복잡 할 수 있지만 추가로 TRIM 길이와 비교할 수 있습니다.
Brian J

이것은 후행 공백 대신 선행 공백이 계산되지 않는 버그를 되돌립니다. 다음 코드를 참조하십시오. declare @TestField varchar(10); SET @TestField = ' abc '; -- Length with spaces is 5. select LEN(REVERSE(@TestField)) -- Returns 4 select LEN(@TestField) -- Returns 4
Metalogic

1

문자열 연결이 마음에 들지 않으면 문자열의 길이 필드를 반환하는 CLR 함수를 정의해야합니다. 내가 사용하는 LEN('x' + @string + 'x') - 2내 생산 사용 사례에.


0

DATALENGTHn / varchar 문제로 인해 싫어하는 경우 다음을 수행하십시오 .

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

그것은 단지

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

0으로 나누기 보호로 래핑됩니다.

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

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


-4

SELECT DATALENGTH ( 'string') 사용


2
7 년 전의 다른 사람의 답변을 다시 작성했으며 제공 업체는 새로운 내용이 없거나 답변이 무엇인지 또는 그 질문에 어떻게 답변하는지 설명합니다.
Jpsh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.