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
길이 결과에 후행 공백을 어떻게 포함합니까?
답변
이것은 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
답변
이 트릭을 사용할 수 있습니다.
LEN (Str + ‘x’)-1
답변
이 방법을 사용합니다.
LEN(REPLACE(TestField, ' ', '.'))
이것은 다른 데이터 유형에서 작동하기 때문에 DATALENGTH보다 선호하고 문자열이 이미 최대 길이에있는 경우에 대해 걱정할 필요가 없기 때문에 끝에 문자를 추가하는 것보다 선호합니다.
참고 : 매우 큰 데이터 세트에 대해 사용하기 전에 성능을 테스트합니다. 2M 행에 대해 테스트했지만 REPLACE 없이는 LEN보다 느리지 않았습니다.
답변
“길이 결과에 후행 공백을 어떻게 포함합니까?”
여기에있는이 놀랍도록 간단한 문제에 대해 나열된 거의 모든 해결 방법에 결함이 있거나 비효율적이기 때문에 누군가 SQL Server 향상 요청 / 버그 보고서를 제출하게됩니다. 이것은 SQL Server 2012에서도 여전히 사실 인 것처럼 보입니다. 자동 트리밍 기능은 ANSI / ISO SQL-92에서 비롯된 것일 수 있지만 몇 가지 구멍이있는 것 같습니다 (또는 계산 부족).
여기에서 “LEN이 후행 공백을 계산하도록 설정 추가”에 투표하십시오.
폐기 된 연결 링크 :
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으로 나누기). 이 여부를 작동 @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의 경우) 인 가장자리 케이스에 대한 보호 기능이있어 이에 대한 정답이 제공됩니다. 또한 서로 게이트 쌍이있는 문자열을 올바르게 처리해야합니다.
답변
또한 데이터가 실제로 후행 공백으로 저장되었는지 확인해야합니다. 때 ANSI 패딩 OFF (기본이 아닌)이다 :
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)
물론 선행 공백에는 사용하지 마십시오.
