UCS-2 인코딩은 문자 당 항상 2 바이트이며 범위는 0-65535 (0x0000-0xFFFF)입니다. UTF-16 (Big Endian 또는 Little Endian에 관계없이)의 범위는 0-1114111 (0x0000-0x10FFFF)입니다. UTF-16의 0-65535 / 0x0000-0xFFFF 범위는 문자 당 2 바이트 인 반면 65536 / 0xFFFF 이상의 범위는 문자 당 4 바이트입니다.
Windows와 SQL Server는 UCS-2 인코딩을 사용할 수 있었고 UTF-16이 아직 마무리되지 않았기 때문에 시작했습니다. 그러나 UCS-2와 UTF-16의 디자인에는 UCS-2 매핑이 UTF-16 매핑의 완전한 하위 집합이라는 의미가 충분히 있습니다 (즉, 0-65535 / 0x0000-0xFFFF 범위). UTF-16 은 UCS-2입니다). UTF-16의 65536-1114111 (0x10000-0x10FFFF) 범위는 UCS-2 범위의 두 코드 포인트 (범위 0xD800 – 0xDBFF 및 0xDC00 – 0xDFFF 범위)로 구성되며, 그렇지 않은 경우에는 의미. 이 두 코드 포인트의 조합을 대리 쌍이라고하며 대리 쌍은 보충 문자로 알려진 UCS-2 범위를 벗어난 문자를 나타냅니다.
이 모든 정보는 NVARCHAR
SQL Server에서 / 유니 코드 데이터 의 두 가지 측면을 설명합니다 .
- 여러 내장 함수 (다만
NCHAR()
보충 문자 인식 데이터 정렬 사용하지 않을 경우 대리 쌍 / 보조 문자를 처리하지 않는) (SCA를, 즉 하나 _SC
, 또는 _140_
하지만 _BIN*
이름에서) 때문에 비 SCA 데이터 정렬 (특히 SQL_
데이터 정렬)은 원래 UTF-16이 완료되기 전에 구현되었습니다 (때로는 2000 년에 믿습니다). 이름 SQL_
이 _90_
있거나 _100_
이름은 있지만 _SC
비교 및 정렬 측면에서 보충 문자를 최소한으로 지원 하지 않는 비 콜 레이션 .
- 전체 유니 코드 / UTF-16 문자 세트로는, 데이터 손실없이 저장 될 수있는
NVARCHAR
/ NCHAR
/ XML
/ NTEXT
데이터 유형 UCS-2 및 UTF-16이 동일한 바이트 시퀀스이기 때문에. 유일한 차이점은 UTF-16은 서로 게이트 코드 포인트를 사용하여 서로 게이트 쌍을 구성한다는 점입니다. UCS-2는 단순히 문자를 매핑 할 수 없으므로 내장 함수에 두 개의 알 수없는 문자로 표시됩니다.
이러한 배경 정보를 염두에두고 이제 다음과 같은 구체적인 질문을 수행 할 수 있습니다.
SELECT NCHAR(128512);
다음과 같이 반환하고 싶습니다 .SELECT N'😀';
쿼리가 실행되는 현재 데이터베이스에 보조 문자 인식 보조 기본 인식 데이터 정렬이 있고 SQL Server 2012에 도입 된 기본 데이터 정렬이있는 경우에만 발생할 수 있습니다. 문자열 입력 매개 변수가있는 기본 제공 함수는 데이터 정렬을 제공 할 수 있습니다. COLLATE
절 (예 :)을 통해 인라인 하고 SCA 기본 데이터 정렬이있는 데이터베이스 내에서 실행될 필요LEN(N'string' COLLATE Some_Collation_SC)
가 없습니다 . 그러나 입력 매개 변수 를 받아들이고 해당 절 에서 절이 유효하지 않은 내장 함수 ( 현재 데이터베이스에 보조 문자 인식 보조 기본 정렬이있는 경우 보조 문자 만 지원 하는 이유 는 필요하지 않습니다) 불편을 끼쳐 드려 죄송합니다. 제 의견에 투표 해주세요.NCHAR()
INT
COLLATE
NCHAR()
NCHAR () 함수는 활성 데이터베이스의 기본 데이터 정렬에 관계없이 항상 0x10000-0x10FFFF 값에 대해 보충 문자를 반환해야합니다 .)
데이터 정렬에 관계없이 SQL Server가 관점을 제외하고 확장 문자를 이해하고 처리 할 수있는 이유에 대한 설명이 NCHAR
있습니까?
SQL Server가 데이터 손실없이 보충 문자를 저장하고 검색하는 방법은이 답변의 맨 위 섹션에 설명되어 있습니다. 그러나 NCHAR
보조 문자 (SCA 데이터 정렬을 사용하지 않는 경우)에 문제가있는 유일한 내장 기능인 것은 사실이 아닙니다. 예를 들어, LEN(N'😀' COLLATE SQL_Latin1_General_CP1_CI_AS)
값 2를 LEN(N'😀' COLLATE Latin1_General_100_CI_AS_SC)
반환하고 값 1 을 반환합니다.
질문에 게시 된 두 번째 링크 (예 : "Microsoft 보조 문자 데이터 정렬 정보")로 이동 한 다음 조금 아래로 스크롤하면 기본 제공 함수 차트와 해당 함수가 효과적인 데이터 정렬을 기반으로 동작하는 방식을 볼 수 있습니다.
"보조 문자"플래그가있는 데이터 정렬을 찾으려면 어떻게합니까?
2012 년 이전의 SQL Server 버전에서는 할 수 없습니다. 그러나 SQL Server 2012부터 다음 쿼리를 사용할 수 있습니다.
SELECT col.*
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'%[_]SC'
OR col.[name] LIKE N'%[_]SC[_]%'
OR (COLLATIONPROPERTY(col.[name], 'Version') = 3
AND col.[name] NOT LIKE N'%[_]BIN%');
쿼리가 닫혔지만 패턴이 시작 SQL
되고 SQL Server 데이터 정렬 (으로 시작하는 데이터 정렬 SQL_
)은 Windows 데이터 정렬 (으로 시작하지 않는)을 위해 한동안 사용되지 않습니다 SQL_
. 따라서 SQL_
데이터 정렬이 업데이트되지 않으므로 _SC
옵션을 포함하는 최신 버전이 없습니다 (SQL Server 2017부터는 모든 새 데이터 정렬이 자동으로 보조 문자를 지원 하며 _SC
플래그 가 필요하거나 없습니다) . 바로 위에 표시된 _UTF8
것은 SQL Server 2019에 추가 된 데이터 정렬 을 선택하는 것 입니다.
이전 인스턴스에 데이터 정렬을 설치할 수 있습니까?
아니요, 이전 버전의 SQL Server에는 데이터 정렬을 설치할 수 없습니다.
데이터 정렬이 "보충 문자 (SC) 플래그를 포함하지 않는"데이터베이스에서 코드 (실제 보충 문자를 사용하지 않고)를 사용하여 유니 코드 문자열 변수 (예 : nvarchar)를 보충 문자로 설정하려면 어떻게해야합니까?
...
서버는 SQL Server 2008 R2이지만 이후 버전의 솔루션에 대해서도 궁금합니다.
SCA 데이터 정렬을 사용하지 않는 경우 다음 두 가지 방법으로 65535 / U + FFFF 이상의 코드 포인트를 삽입 할 수 있습니다.
NCHAR()
함수 에 대한 두 번의 호출로 각각 쌍의 한 부분으로 대리 쌍을 지정하십시오.
VARBINARY
리틀 엔디안 (즉, 역) 바이트 시퀀스 의 형식 을 변환하는 관점에서 대리 쌍을 지정하십시오 .
보충 문자 / 서로 게이트 쌍을 삽입하는이 두 가지 방법은 효과적인 데이터 정렬이 보충 문자 인식 인 경우에도 작동하며 적어도 2005 년까지 모든 SQL Server 버전에서 동일하게 작동해야합니다. SQL Server 2000).
예:
- 캐릭터:
💩
- 이름 : 똥 더미
- 10 진수 : 128169
- 코드 포인트 : U + 1F4A9
- 대리 쌍 : U + D83D 및 U + DF21
SELECT N'💩', -- 💩
UNICODE(N'💩' COLLATE Latin1_General_100_CI_AS), -- 55357
UNICODE(N'💩' COLLATE Latin1_General_100_CI_AS_SC), -- 128169
NCHAR(128169), -- 💩 in DB with _SC Collation, else NULL
NCHAR(0x1F4A9), -- 💩 in DB with _SC Collation, else NULL
CONVERT(VARBINARY(4), 128169), -- 0x0001F4A9
CONVERT(VARBINARY(4), N'💩'), -- 0x3DD8A9DC
CONVERT(NVARCHAR(10), 0x3DD8A9DC), -- 💩 (regardless of DB Collation)
NCHAR(0xD83D) + NCHAR(0xDCA9) -- 💩 (regardless of DB Collation)
최신 정보
다음 iTVF를 사용하여 65536-1114111 (0x010000-0x10FFFF) 사이의 코드 포인트에서 Surrogate Pair 값 ( 양식 INT
및 BINARY
형식) 을 얻을 수 있습니다 . 또한 입력 매개 변수가 유형 인 동안 INT
코드 포인트의 2 진 / 16 진 형식을 전달하면 암시 적으로 올바른 정수 값으로 변환됩니다.
CREATE FUNCTION dbo.GetSupplementaryCharacterInfo(@CodePoint INT)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN
WITH calc AS
(
SELECT 55232 + (@CodePoint / 1024) AS [HighSurrogateINT],
56320 + (@CodePoint % 1024) AS [LowSurrogateINT]
WHERE @CodePoint BETWEEN 65536 AND 1114111
)
SELECT @CodePoint AS [CodePointINT],
HighSurrogateINT,
LowSurrogateINT,
CONVERT(VARBINARY(3), @CodePoint) AS [CodePointBIN],
CONVERT(BINARY(2), HighSurrogateINT) AS [HighSurrogateBIN],
CONVERT(BINARY(2), LowSurrogateINT) AS [LowSurrogateBIN],
CONVERT(binary(4), NCHAR(HighSurrogateINT) + NCHAR(LowSurrogateINT)) AS [UTF-16LE],
NCHAR(HighSurrogateINT) + NCHAR(LowSurrogateINT) AS [Character]
FROM calc;
GO
위의 함수를 사용하여 다음 두 쿼리가 있습니다.
SELECT * FROM dbo.GetSupplementaryCharacterInfo(128169);
SELECT * FROM dbo.GetSupplementaryCharacterInfo(0x01F4A9);
둘 다 다음을 반환합니다.
CodePoint HighSurrogate LowSurrgate CodePoint HighSurrgate LowSurrgate UTF-16LE Char
INT INT INT BIN BIN BIN actr
128169 55357 56489 0x01F4A9 0xD83D 0xDCA9 0x3DD8A9DC 💩
업데이트 2 : 더 나은 업데이트!
위에 표시된 iTVF를 조정하여 이제 188,657 개의 코드 포인트를 반환하므로 특정 값에 맞출 필요가 없습니다. 물론 TVF 인 WHERE
경우 특정 코드 포인트 또는 코드 포인트 범위 또는 "유사 문자"등을 필터링 하는 절을 추가 할 수 있습니다 . 또한 각 코드를 구성하기 위해 사전 형식화 된 이스케이프 시퀀스가있는 추가 열이 포함됩니다. 포인트 T-SQL, HTML에서 (모두 BMP 및 보조 캐릭터), 그리고 C 스타일 (예 \xHHHH
). 여기에 대한 모든 내용을 읽으십시오.
SSMS Tip # 3 : 모든 유니 코드 문자를 쉽게 액세스 / 연구 (예, 이모티콘 포함)