SQL Server에서 이러한 문자가 모두 같은 이유는 무엇입니까?


20

나는 그것을 얻지 못한다. 이 SQL 쿼리를 참조하십시오.

select nchar(65217) -- ﻁ
select nchar(65218) -- ﻂ
select nchar(65219) -- ﻃ
select nchar(65220) -- ﻄ
if nchar(65217) = nchar(65218)
    print 'equal'
if nchar(65217) = nchar(65219)
    print 'equal'
if nchar(65217) = nchar(65220)
    print 'equal'

전 이적 관계를 기반으로 , 이는 SQL Server가 모두 동일한 문자로 간주 함을 의미합니다.

그러나 C #과 같은 다른 환경에서는 동일하지 않습니다.

내가 혼란스럽게하는 것은 :

  1. SQL Server에서 문자열 비교 작동 방식
  2. 비교가 하나의 시스템과 하나의 플랫폼에서 동일하지 않지만 다른 환경에서 작동하는 이유
  3. 이 4 자 대표 사람이 이해할 수있는 캐릭터. 왜 유니 코드 문자표가 그토록 풍부합니까?

물론 텍스트 처리 응용 프로그램을 작업 중이며 데이터가 거의 모든 곳에서 나오므로 처리하기 전에 텍스트를 정규화해야하기 때문에 엄청난 문제가 발생합니다.

차이점이있는 이유를 알고 있으면이를 해결할 솔루션을 찾을 수 있습니다. 고맙습니다.

답변:


28

SQL Server의 모든 문자 데이터는 데이터 정렬과 연결되어 데이터를 비교하고 정렬하는 데 사용되는 규칙뿐만 아니라 저장할 수있는 문자 도메인을 결정합니다. 데이터 정렬은 유니 코드 및 비 유니 코드 데이터 모두에 적용됩니다.

SQL Server에는 이진, 레거시 및 Windows의 세 가지 범주의 데이터 정렬이 포함됩니다. 이진 범주 ( _BIN접미사) 의 데이터 정렬 은 기본 코드 포인트를 사용하여 비교하므로 코드 포인트가 문자에 관계없이 다르면 동등 비교가 같지 않습니다. 레거시 ( SQL_접두사) 및 Windows 데이터 정렬은보다 자연스러운 사전 규칙에 대한 정렬 및 비교 시맨틱을 제공합니다. 이를 통해 비교시 대소 문자, 악센트, 너비 및 가나를 고려할 수 있습니다. Windows 데이터 정렬 word-sort은 Windows OS와 밀접하게 일치 하는보다 강력한 규칙을 제공 하지만 레거시 데이터 정렬은 단일 문자 만 고려합니다.

아래 예제는 Windows와 Teth 문자를 사용한 이진 데이터 정렬의 차이점을 보여줍니다.

CREATE TABLE dbo.WindowsColationExample
    (
      Character1 nchar(1) COLLATE Arabic_100_CI_AS_SC
    , Character2 nchar(1) COLLATE Arabic_100_CI_AS_SC
    , Character3 nchar(1) COLLATE Arabic_100_CI_AS_SC
    , Character4 nchar(1) COLLATE Arabic_100_CI_AS_SC
    );

CREATE TABLE dbo.BinaryColationExample
    (
      Character1 nchar(1) COLLATE Arabic_100_BIN
    , Character2 nchar(1) COLLATE Arabic_100_BIN
    , Character3 nchar(1) COLLATE Arabic_100_BIN
    , Character4 nchar(1) COLLATE Arabic_100_BIN
    );

INSERT  INTO dbo.BinaryColationExample
VALUES  ( NCHAR(65217), NCHAR(65218), NCHAR(65219), NCHAR(65220) );
INSERT  INTO dbo.WindowsColationExample
VALUES  ( NCHAR(65217), NCHAR(65218), NCHAR(65219), NCHAR(65220) );

--all characters compare not equal
SELECT *
FROM dbo.BinaryColationExample
WHERE
    character1 = character2
    OR character1 = character3
    OR character1 = character4
    OR character2 = character3
    OR character2 = character4
    OR character3 = character4;

--all characters compare equal
SELECT *
FROM dbo.WindowsColationExample
WHERE character1 = character2;
SELECT *
FROM dbo.WindowsColationExample
WHERE character1 = character3;
SELECT *
FROM dbo.WindowsColationExample
WHERE character1 = character4;
SELECT *
FROM dbo.WindowsColationExample
WHERE character2 = character3;
SELECT *
FROM dbo.WindowsColationExample
WHERE character2 = character4;
SELECT *
FROM dbo.WindowsColationExample
WHERE character3 = character4;

유니 코드에 동일한 글리프에 대해 다른 코드 포인트가 포함될 수있는 이유는 http://en.wikipedia.org/wiki/Duplicate_characters_in_Unicode에 나와 있습니다. 요약하면, 레거시 호환성을위한 것일 수도 있고 문자가 정식으로 동일하지 않을 수도 있습니다. Teth 문자 는 다른 언어로 사용됩니다 ( http://en.wikipedia.org/wiki/Teth ).


15

이것은 COLLATION데이터베이스 와 관련이 있습니다 ( BOL의 자세한 정보 ).

나는 당신이 문제를 겪고있는 특정 캐릭터의 언어를 완전히 확신하지 못하지만 ( 스레드를 기반으로 페르시아를 추측 하고 있습니다) 평등 연산자에 올바른 데이터 정렬을 지정하면 정확한 결과를 얻을 수 있습니다.

if nchar(65217) COLLATE Persian_100_BIN = nchar(65218) COLLATE Persian_100_BIN 
    print 'equal'; -- nothing returned
if nchar(65217)  COLLATE Persian_100_BIN  = nchar(65217)  COLLATE Persian_100_BIN 
    print 'equal'; -- prints 'equal'
if nchar(65217) COLLATE Latin1_General_CI_AI = nchar(65220) COLLATE Latin1_General_CI_AI
    print 'equal'; -- prints 'equal'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.