@gbn은 이미 기본 이유와 수정을 설명했지만 현재보고있는 동작의 구체적인 이유는 다음과 같습니다.
- 당신은 사용하는
VARCHAR
문자 (NO N
접두사) 대신의 NVARCHAR
문자 (와 문자열 N
접두어), 따라서 유니 코드 문자로 변환되는 것이다 VARCHAR
.
VARCHAR
대부분의 경우 문자 당 1 바이트이지만 문자 당 2 바이트 일 수있는 8 비트 인코딩입니다. 반면에 NVARCHAR
문자 당 2 바이트 또는 4 바이트 인 16 비트 인코딩 (UTF-16 Little Endian)입니다.
- 문자를 매핑하는 데 사용할 수있는 바이트 수의 차이로 인해 8 비트 인코딩은 그 특성상 매핑 할 수있는 문자 수가 훨씬 더 제한됩니다.
VARCHAR
데이터는 1 바이트 문자 세트 (대부분)의 경우 최대 256 자이고 2 바이트 문자 세트 (대부분의 숫자)의 경우 최대 65,536 자입니다. 반면, NVARCHAR
데이터는 110 만 개 이상의 유니 코드 문자를 매핑 할 수 있습니다 (현재 매핑 된 250k 미만).
- 8 비트 /
VARCHAR
데이터 로 수행 할 수있는 매핑 수가 제한되어 있기 때문에 (언어 / 문화를 기반으로하는) 문자 그룹이 여러 "코드 페이지"(예 : 문자 세트)에 분산됩니다.
- 각 데이터 정렬은 데이터에 사용할 코드 페이지 (있는 경우)를 지정
VARCHAR
합니다 ( NVARCHAR
모든 문자 임)
- 문자열 리터럴 또는 변수를
NVARCHAR
(예 : 유니 코드 / UTF-16 / 모든 문자)에서 VARCHAR
(대부분의 데이터 정렬에 지정된 코드 페이지를 기반으로하는 문자 세트 )로 변환 할 때 데이터베이스의 기본 데이터 정렬이 사용됩니다
- 변환에 사용되는 데이터 정렬의 코드 페이지에 동일한 문자가 없지만 "최 적합"매핑이 포함 된 경우 "최 적합"매핑이 사용됩니다.
- 변환에 사용되는 데이터 정렬의 코드 페이지에 동일한 문자가 없거나 "가장 적합"매핑이 포함 된 경우 기본 "대체"문자가 사용됩니다 (가장 일반적으로
?
).
그래서, 당신이보고있는 것은입니다 NVARCHAR
로 VARCHAR
인해 누락 변환을 N
문자열 리터럴에 접두사. 그리고 데이터베이스에 대한 기본 데이터 정렬의 코드 페이지에 정확히 동일한 문자가 포함되어 있지 않지만 "최적의"매핑이 발견 되었기 때문에 . 2
대신을 (를) 받고 ?
있습니다.
다음과 같은 간단한 테스트를 수행하여이 효과를 볼 수 있습니다.
SELECT '₂', N'₂';
보고:
2 ₂
분명히 데이터베이스의 기본 데이터 정렬의 코드 페이지에 정확히 동일한 문자가 포함되어 있으면 해당 코드 페이지에서 동일한 문자로 변환 된 것입니다. 그런 다음 NVARCHAR
열에 저장 하기 때문에 원래의 유니 코드 문자로 다시 변환되었을 것입니다. 아래의 마지막 예는이 동작을 보여줍니다.
중요 : 문자열 리터럴을 해석 할 때 열에 저장 되기 전에 변환이 수행됩니다. 이는 열이 해당 문자를 보유 할 수있는 경우에도 N
해당 문자열 리터럴의 접 두부 를 생략하여 데이터베이스의 기본 데이터 정렬을 기반으로 이미 다른 문자로 변환되었음을 의미합니다. 그리고 이것은 정확히 당신이 경험 한 것입니다.
예를 들어, 데이터베이스의 기본 데이터 정렬이 한국어 데이터 정렬 중 하나 (4 개의 2 바이트 문자 집합 중 하나) 인 경우 해당 문자에서 "아래 첨자 2"문자를 사용할 수 있으므로이 문제를 보지 못했을 것입니다. 설정 (코드 페이지 949). 다음 테스트를 수행하여 확인하십시오 (데이터베이스의 기본 데이터 정렬 대신 열의 데이터 정렬을 사용하는 것이 더 쉽습니다).
CREATE TABLE #TestChar
(
[8bit_Latin1_General-1252] VARCHAR(2) COLLATE Latin1_General_100_CI_AS_SC,
[8bit_Korean-949] VARCHAR(2) COLLATE Korean_100_CI_AS_SC,
[UTF16LE_Latin1_General-1252] NVARCHAR(2) COLLATE Latin1_General_100_CI_AS_SC
);
INSERT INTO #TestChar VALUES (N'₂', N'₂', N'₂');
SELECT * FROM #TestChar;
보고:
8bit_Latin1_General-1252 8bit_Korean-949 UTF16LE_Latin1_General-1252
2 ₂ ₂
보다시피, 데이터에 Code Page 1252 ( Modern_Spanish
Collations에서 사용 하는 것과 동일한 Code Page)를 사용하는 Latin1_General Collations VARCHAR
는 정확히 일치하지는 않지만 " 최 적합"매핑 (현재보고있는 것)을 갖습니다. ). 그러나 데이터에 코드 페이지 949를 사용하는 한국어 데이터 정렬 VARCHAR
은 "아래 첨자 2"문자와 정확히 일치합니다.
더 자세히 설명하기 위해 한국어 데이터 정렬 중 하나의 기본 데이터 정렬을 사용하여 새 데이터베이스를 만든 다음 질문에있는 정확한 SQL을 실행할 수 있습니다.
CREATE DATABASE [TestKorean-949] COLLATE Korean_100_CI_AS_KS_WS_SC;
ALTER DATABASE [TestKorean-949] SET RECOVERY SIMPLE;
GO
USE [TestKorean-949];
CREATE TABLE test (
id INT NOT NULL,
description NVARCHAR(100) COLLATE Modern_Spanish_CI_AS NOT NULL
);
INSERT INTO test (id, description) VALUES (1, 'CO2');
SELECT * FROM test WHERE id = 1;
UPDATE test SET description = 'CO₂' WHERE id = 1;
SELECT * FROM test WHERE id = 1;
보고:
id description
1 CO2
id description
1 CO₂
최신 정보
여기에서 정확히 무슨 일 이 일어나고 있는지에 대해 더 자세히 알고 싶은 사람은 방금 게시 한 두 부분으로 된 조사를 참조하십시오.