programing

SQL Server 2008 빈 문자열과공간

magicmemo 2023. 4. 21. 20:27
반응형

SQL Server 2008 빈 문자열과공간

오늘 아침에 좀 이상한 일이 생겨서 해설을 위해 제출하려고 했어요.

SQL 2008에 대해 실행할 때 다음 SQL 쿼리가 '동일'로 출력되는 이유를 설명해 주시겠습니까?DB 호환성 수준이 100으로 설정되어 있습니다.

if '' = ' '
    print 'equal'
else
    print 'not equal'

이 값은 0을 반환합니다.

select (LEN(' '))

공간을 자동 트리밍하고 있는 것 같습니다.이전 버전의 SQL Server에서도 이 문제가 발생했는지 알 수 없으며 테스트할 시간도 없습니다.

프로덕션 쿼리가 잘못된 결과를 반환하고 있었기 때문에 이 문제에 부딪혔습니다.이 동작은 어디에서도 문서화되어 있지 않습니다.

이것에 대해 아는 사람 있나요?

varchar동등성은 TSQL에서 .LEN을 사용하다

지정된 문자열 표현의 문자 수가 아니라 후행 공백을 제외하고 문자 수를 반환합니다.

'어울리다'를 써야 요.DATALENGTHbyte해당 데이터의 개수입니다.Unicode 데이터가 있는 경우 이 상황에서 얻을 수 있는 값은 텍스트 길이와 동일하지 않습니다.

print(DATALENGTH(' ')) --1
print(LEN(' '))        --0

표현의 평등에 관해서는 두 문자열이 다음과 같이 동등하게 비교됩니다.

  • 짧은 문자열 가져오기
  • 길이가 긴 문자열 길이와 같아질 때까지 공백이 있는 패드
  • 이 둘을 비교하다

예기치 않은 결과를 초래하는 것은 중간 단계입니다. 이 단계 이후 공백과 공백을 효과적으로 비교하기 때문에 동일한 것으로 보입니다.

LIKE=대조하려고 하는 패턴에서는 블랭크 스탬프가 실행되지 않기 때문에, 「스탬프」의 상황에서는 다음과 같이 됩니다.

if '' = ' '
print 'eq'
else
print 'ne'

줄줄 will will 를 주다eq 삭제:

if '' LIKE ' '
print 'eq'
else
print 'ne'

줄줄 will will 를 주다ne

LIKE단, 대칭은 아닙니다.후행 공백은 패턴(RHS)에서 중요한 것으로 취급하지만 일치식(LHS)은 취급하지 않습니다.여기서부터의 내용은 다음과 같습니다.

declare @Space nvarchar(10)
declare @Space2 nvarchar(10)

set @Space = ''
set @Space2 = ' '

if @Space like @Space2
print '@Space Like @Space2'
else
print '@Space Not Like @Space2'

if @Space2 like @Space
print '@Space2 Like @Space'
else
print '@Space2 Not Like @Space'

@Space Not Like @Space2
@Space2 Like @Space

T-SQL의 = 연산자는 "표현 문맥의 조합에 따라 동일한 단어/구절"이라기보다는 "구절"이며, LEN은 "단어/구절의 문자 수"입니다.정렬에서는 후행 공백을 단어/구문의 일부로 취급하지 않습니다(단, 선행 공백을 선행 문자열의 일부로 취급합니다).

'this'와 'this'를 구분할 필요가 있는 경우 'this'와 'this'는 같은 단어이므로 'are same word or phrase' 연산자를 사용하지 마십시오.

=의 작동 방식에 기여하는 것은 문자열 검색 연산자가 인수의 내용과 식의 대조 컨텍스트에 의존해야 하지만 둘 다 문자열 유형인 경우 인수의 유형에 의존해서는 안 된다는 것입니다.

자연어 "these are same word"라는 자연어 개념은 일반적으로 =와 같은 수학적 연산자가 포착할 수 있을 만큼 정확하지 않으며 자연어에는 문자열 유형의 개념이 없습니다.맥락(예: 조합)이 중요하며(자연 언어로 존재하며) 이야기의 일부이며, 부자연스러운 데이터 세계에서 잘 정의되도록 하기 위해 =의 정의의 일부 추가 속성(예: 별난 속성)이 포함되어 있습니다.

유형 문제에서는 다른 문자열 유형에 저장될 때 단어가 변경되지 않도록 할 수 있습니다.예를 들어 VARCHAR(10), CHAR(10) 및 CHAR(3) 유형은 모두 단어 'cat' 표현을 유지할 수 있으며, ? = 'cat'은 이러한 유형의 값이 단어 'cat'을 보유하는지 여부를 결정할 수 있어야 한다(대소문자와 악센트가 대조로 결정됨).

JohnFx의 코멘트에 대한 응답:

온라인 북스에서 charvarchar 데이터 사용을 참조하십시오.이 페이지를 인용해서 강조하겠습니다.

각 char 및 varchar 데이터 값에는 조회가 있습니다.대조는 각 문자를 나타내기 위해 사용되는 비트 패턴, 비교 규칙, 대소문자 또는 악센트에 대한 민감도 등의 속성을 정의합니다.

찾기가 더 쉬울 수 있다는 건 인정하지만 문서화되어 있어요

또한 =가 실제 데이터와 관련이 있으며 비교의 맥락(컴퓨터에 저장된 비트와는 대조적으로)이 오랫동안 SQL의 일부였다는 점도 주목할 필요가 있습니다.RDBMS와 SQL의 전제는 실제 데이터를 충실하게 표현하는 것입니다.따라서 비슷한 아이디어(CultureInfo 등)가 Algol과 유사한 언어의 영역에 진입하기 몇 년 전에 RDBMS와 SQL의 조합이 지원되었습니다.이러한 언어(최소한 최근까지)의 전제는 비즈니스 데이터 관리가 아닌 엔지니어링에서의 문제 해결이었습니다.(최근에는 검색과 같은 엔지니어링 이외의 애플리케이션에서 유사한 언어를 사용하는 것이 어느 정도 침투하고 있지만 Java, C# 등은 여전히 비즈니스 이외의 뿌리에서 어려움을 겪고 있습니다.)

제 생각에는 SQL이 "대부분의 프로그래밍 언어"와 다르다고 비판하는 것은 공정하지 않습니다.SQL은 엔지니어링과는 매우 다른 비즈니스 데이터 모델링을 위한 프레임워크를 지원하도록 설계되었기 때문에 언어가 다르며 목표 달성에도 더 적합합니다.

SQL이 처음 지정되었을 때 일부 언어에는 내장된 문자열 유형이 없었습니다.또한 일부 언어에서는 문자열 사이의 등호 연산자가 문자 데이터를 전혀 비교하지 않고 참조를 비교합니다.앞으로 10~20년 후에 ==가 문화에 의존한다는 생각이 일반적이 되어도 전혀 놀랍지 않을 것입니다.

나는 행동을 설명하고 그 이유를 설명하는 이 블로그 기사를 발견했다.

SQL 표준에서는 문자열 비교를 통해 짧은 문자열을 공백 문자로 효과적으로 채워야 합니다.이는 N' = N'이라는 놀라운 결과로 이어집니다(빈 문자열은 하나 이상의 공백 문자로 이루어진 문자열에 해당함). 그리고 일반적으로 후행 공백으로만 다른 문자열과 동일한 문자열입니다.이것은 상황에 따라서는 문제가 될 수 있습니다.

자세한 내용은 MSKB316626에서도 확인 가능

얼마 전에 비슷한 질문을 했는데 여기서 비슷한 문제를 조사했습니다.

대신LEN(' '),사용하다DATALENGTH(' ')- 올바른 값을 제공합니다.

해결방법은 다음과 같습니다.LIKE내 답변에 설명된 조항 및/또는 두 번째 조건을 포함합니다.WHERE확인할 조항DATALENGTH너무.

그 질문과 링크를 읽어보세요.

값을 리터럴 공간과 비교하려면 LIKE 문 대신 다음 기술을 사용할 수도 있습니다.

IF ASCII('') = 32 PRINT 'equal' ELSE PRINT 'not equal'

Null을 사용하는 것이 더 좋지만 항상 사용할 수 있는 것은 아니지만 다른 문자가 있든 없든 데이터 내의 공백을 처리해야 하는 경우가 있습니다.저는 위에 설명한 상황에 부딪혔고, 이렇게 해결했습니다.

... where ('>' + @space + '<') <> ('>' + @space2 + '<')

물론 대량의 데이터에는 대응하지 않지만, 몇백 회선에서는 빠르고 간단하게 동작합니다.

SQL - 92 8.2 비교 술어로서 다음과 같이 기술되어 있습니다.

X 문자의 길이가 Y 문자의 길이와 동일하지 않은 경우 비교하기 위해 짧은 문자열은 1개 또는 여러 패드 문자의 오른쪽에 연결하여 긴 문자열의 길이로 확장한 자신의 복사본으로 효과적으로 대체됩니다.여기서 패드 문자는 CS를 기반으로 선택됩니다.CS에 NO PAD 속성이 설정되어 있는 경우 패드 문자는 X 및 Y 문자 집합의 어떤 문자와도 다르며 CS 아래의 어떤 문자열보다 적게 조합됩니다.그렇지 않으면 패드 문자는<space>.

select의 레코드를 sql 서버에서 char/varchar 필드로 구별하는 방법: 예:

declare @mayvar as varchar(10)

set @mayvar = 'data '

select mykey, myfield from mytable where myfield = @mayvar

기대됩니다

mykey (int) | myfield (varchar10)

1 | '데이터'

취득했다

마이키 | myfield

1 | '데이터' 2 | '데이터'

가 가가글 even even라고 select mykey, myfield from mytable where myfield = 'data'이데올로기 때문에

어떻게 해결했을까요?이 모드에서는:

select mykey, myfield
from mytable
where myfield = @mayvar 
and DATALENGTH(isnull(myfield,'')) = DATALENGTH(@mayvar)

만약 마이필드에 지표가 있다면, 각각의 경우에 사용될 것입니다.

도움이 되었으면 좋겠습니다.

또 다른 방법은 공간에 가치가 있는 상태로 되돌리는 것입니다.예: 공백을 _와 같은 문자로 바꿉니다.

if REPLACE('hello',' ','_') = REPLACE('hello ',' ','_')
    print 'equal'
else
    print 'not equal'

반환: 동일하지 않음

이상적이지 않고 느릴 수 있지만, 필요할 때 빠르게 전진할 수 있는 또 다른 방법입니다.

언급URL : https://stackoverflow.com/questions/1399844/sql-server-2008-empty-string-vs-space

반응형