동일한 비교에서 varchar 값의 SQL Server 자동 트림


13

나는 누군가 누군가 설명 할 수 있기를 희망하면서 SQL Server에서 흥미로운 행동을 보았습니다 (2005 년과 2012 년에 관찰).

=NVARCHAR 필드를 사용하여 비교를 수행하는 쿼리 는 문자열의 후행 공백을 무시했거나 비교 전에 값을 자동 트리밍했지만 like연산자를 사용한 동일한 쿼리 는 공백을 무시하지 않았습니다. 사용되는 데이터 정렬은 2012 년의 Latin1_General_CI_AS입니다.

이 SQL Fiddle을 고려하십시오 : http://sqlfiddle.com/#!6/72262/4

점을 유의 like운영자가 후행 공백 문자열을 결과를 반환하지 않습니다,하지만 =운영자는 않습니다. 왜 이런거야?

보너스 포인트 : VARCHAR 필드에서 이것을 복제 할 수 없습니다. 두 데이터 유형 모두에서 동일한 방식으로 공백이 처리 될 것이라고 생각했을 것입니다. 이것이 사실입니까?


문자열이 잘렸다는 확인 제약 조건을 작성하려고했습니다. 이 블로그에서MyString+'x' = ltrim(rtrim(MyString))+'x' 제안한대로 확인하는 해결 방법을 찾았습니다
default.kramer

답변:


15

내 초기 답변은 ANSI_PADDING 플래그가 OFF로 설정되어 동작의 차이를 비난 할 수 있다고 제안했습니다. 그러나 이것은 잘못된 것입니다. 이 플래그는 스토리지에만 영향을 미치지 만 평등 비교에는 영향을 미치지 않습니다.

차이점은 Microsoft의 SQL 표준 구현 에서 비롯됩니다 . 표준에 따르면 등식을 검사 할 때 등호 연산자의 왼쪽과 오른쪽 문자열은 모두 같은 길이를 갖도록 채워 져야 합니다. 다음과 같은 결과가 설명됩니다.

insert into test_padding (varchar_clmn, nvarchar_clmn) values ('space ', 'nspace ')
go
-- equality for varchar column
select count(*) from test_padding where varchar_clmn = 'space' -- returns 1
select count(*) from test_padding where varchar_clmn = 'space ' -- returns 1
select count(*) from test_padding where varchar_clmn = 'space    ' --returns 1
-- equality for nvarchar column
select count(*) from test_padding where nvarchar_clmn = 'nspace' -- returns 1
select count(*) from test_padding where nvarchar_clmn = 'nspace ' -- returns 1
select count(*) from test_padding where nvarchar_clmn = 'nspace    ' --returns 1

LIKE 연산자는 피연산자를 채우지 않습니다. 또한 열 유형 VARCHAR과 다르게 작동 NVARCHAR합니다 .

-- likeness for varchar column
select count(*) from test_padding where varchar_clmn like 'space' -- returns 1
select count(*) from test_padding where varchar_clmn like 'space ' -- returns 1
select count(*) from test_padding where varchar_clmn like 'space    ' -- returns 0
-- likeness for nvarchar column
select count(*) from test_padding where nvarchar_clmn like 'nspace' -- returns 0
select count(*) from test_padding where nvarchar_clmn like 'nspace ' -- returns 1
select count(*) from test_padding where nvarchar_clmn like 'nspace    ' -- returns 0

ASCII 유형에 대한 LIKE 연산자의 동작은 SQL Server에 따라 다릅니다. 유니 코드 유형의 경우 ANSI와 호환됩니다.


4

SQL은 대부분의 데이터 처리 언어가 모든 필드 / 변수에 대해 고정 길이를 사용하던 시대에 탄생했습니다. 여분의 공백이있는 텍스트 필드의 자동 채우기도 해당 그림의 일부였습니다. 해당 동작에 맞추기 위해, 원래 SQL CHAR 유형은 '='연산자에 대해 후행 공백을 무시하도록 명시 적으로 정의되었습니다. (이 이상한 것을 발견하면 텍스트에 추가 된 후행 공백이 실제 비즈니스 의미를 갖는 매력적인 사례를 보여주십시오 .)

SQL CHAR 유형은 그 이후로 모든 종류의 방향으로 발전해 왔지만,보다 현대적인 특정 데이터 유형이 여전히 이전의 데이터 유형에서 일부 특성을 상속 한 것은 불가능합니다.


"텍스트에 추가 된 후행 공백이 실제 비즈니스 의미를 갖는 매력적인 사례를 보여줍니다."-특정 원시 콘솔 출력 및 안전하지 않은 XML 단편과 같은 공백으로 중요한 데이터를 저장합니다.
Dai

1

에 대한 문서에서 LIKE (Transact-SQL)를 참조하십시오 , 마이크로 소프트 (강조 광산) 글을 참고하세요 :

LIKE를 사용하여 패턴 일치

LIKE는 ASCII 패턴 일치 및 유니 코드 패턴 일치를 지원합니다. 모든 인수 ...가 ASCII 문자 데이터 유형 인 경우 ASCII 패턴 일치가 수행됩니다. 인수 중 하나가 유니 코드 데이터 유형 인 경우 모든 인수가 유니 코드로 변환되고 유니 코드 패턴 일치가 수행됩니다. LIKE와 함께 유니 코드 데이터를 사용하면 후행 공백이 중요합니다. 그러나 유니 코드가 아닌 데이터의 경우 후미 공백은 중요하지 않습니다. 유니 코드 LIKE는 ISO 표준과 호환됩니다. ASCII LIKE는 이전 버전의 SQL Server와 호환됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.