SQL Server 2008 빈 문자열과공간
오늘 아침에 좀 이상한 일이 생겨서 해설을 위해 제출하려고 했어요.
SQL 2008에 대해 실행할 때 다음 SQL 쿼리가 '동일'로 출력되는 이유를 설명해 주시겠습니까?DB 호환성 수준이 100으로 설정되어 있습니다.
if '' = ' '
print 'equal'
else
print 'not equal'
이 값은 0을 반환합니다.
select (LEN(' '))
공간을 자동 트리밍하고 있는 것 같습니다.이전 버전의 SQL Server에서도 이 문제가 발생했는지 알 수 없으며 테스트할 시간도 없습니다.
프로덕션 쿼리가 잘못된 결과를 반환하고 있었기 때문에 이 문제에 부딪혔습니다.이 동작은 어디에서도 문서화되어 있지 않습니다.
이것에 대해 아는 사람 있나요?
varchar
동등성은 TSQL에서 .LEN
을 사용하다
지정된 문자열 표현의 문자 수가 아니라 후행 공백을 제외하고 문자 수를 반환합니다.
'어울리다'를 써야 요.DATALENGTH
를 byte
해당 데이터의 개수입니다.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의 코멘트에 대한 응답:
온라인 북스에서 char 및 varchar 데이터 사용을 참조하십시오.이 페이지를 인용해서 강조하겠습니다.
각 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
'programing' 카테고리의 다른 글
ARC를 사용하도록 프로젝트를 변환할 때 "스위치 케이스가 보호 범위 내에 있다"는 것은 무엇을 의미합니까? (0) | 2023.04.26 |
---|---|
std:: 문자열을 const char* 또는 char*로 변환하는 방법 (0) | 2023.04.21 |
RichTextBox 문단 간격을 변경하려면 어떻게 해야 합니까? (0) | 2023.04.21 |
기존 Azure Logic App의 이름을 변경하는 방법 (0) | 2023.04.21 |
Swift에서 UIView 서브클래스의 커스텀 init을 작성하려면 어떻게 해야 하나요? (0) | 2023.04.21 |