UCS-2 एन्कोडिंग हमेशा प्रति वर्ण 2 बाइट्स होती है और इसमें 0 - 65535 (0x0000 - 0xFFFF) की सीमा होती है। UTF-16 (बिग एंडियन या लिटिल एंडियन की परवाह किए बिना) की सीमा 0 - 1114111 (0x0000 - 0x10FFFF) है। 0 - 65535 / 0x0000 - UTF-16 की 0xFFFF सीमा प्रति वर्ण 2 बाइट्स है, जबकि 65536 / 0xFFFF से ऊपर की सीमा 4 बाइट प्रति वर्ण है।
विंडोज और SQL सर्वर ने UCS-2 एन्कोडिंग का उपयोग करना शुरू कर दिया क्योंकि यह उपलब्ध था और UTF-16 को अभी तक अंतिम रूप नहीं दिया गया था। सौभाग्य से, हालांकि, यूसीएस -2 और यूटीएफ -16 के डिजाइनों में पर्याप्त विचार किया गया था कि यूसीएस -2 मैपिंग यूटीएफ -16 मैपिंग का एक पूर्ण उपसमुच्चय है (जिसका अर्थ है: 0 - 655535 / 0x0000 - 0xFFFF रेंज UTF-16 की है यूसीएस -2)। और, UTF-16 की 65536 - 1114111 (0x10000 - 0x10FFFF) श्रेणी का निर्माण UCS-2 रेंज (0xD800 - 0xDBFF - 0xDBFF और 0xDC00 - 0xDFFF) में दो कोड पॉइंट्स से किया गया है, विशेष रूप से जो इस उद्देश्य के लिए आरक्षित थे और अन्यथा उनकी कोई आवश्यकता नहीं है। जिसका अर्थ है। दो कोड पॉइंट्स के इस संयोजन को एक सरोगेट जोड़ी के रूप में जाना जाता है, और सरोगेट जोड़े UCS-2 रेंज से परे वर्णों का प्रतिनिधित्व करते हैं जिन्हें पूरक वर्ण के रूप में जाना जाता है।
सभी जानकारी NVARCHAR
SQL सर्वर में / यूनिकोड डेटा के दो पहलुओं की व्याख्या करती है :
- कई अंतर्निहित कार्य (सिर्फ नहीं
NCHAR()
) एक सप्लीमेंट्री कैरेक्टर-एवेयर Collation (SCA; यानी एक के साथ _SC
, या नाम में _140_
नहीं _BIN*
) का उपयोग न करने पर सरोगेट पेयर / सप्लीमेंट्री कैरेक्टर को हैंडल नहीं करते हैं क्योंकि नॉन-एससीएल कोलाइज़ेशन (विशेष रूप से) SQL_
Collations) मूल रूप से 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'😀';
यह केवल तभी हो सकता है जब वर्तमान डेटाबेस - जहां क्वेरी निष्पादित हो रही है - एक डिफ़ॉल्ट Collation है जो अनुपूरक चरित्र-एवेयर है, और जिन्हें SQL सर्वर 2012 में पेश किया गया था। अंतर्निहित कार्यों में स्ट्रिंग इनपुट पैरामीटर हैं जो कोलिशन प्रदान कर सकते हैं। COLLATE
क्लॉज़ (यानी LEN(N'string' COLLATE Some_Collation_SC)
) के माध्यम से इनलाइन और एक SCA डिफ़ॉल्ट Collation वाले डेटाबेस के भीतर निष्पादित करने की आवश्यकता नहीं है । हालाँकि, अंतर्निहित कार्य जैसे कि इनपुट पैरामीटर NCHAR()
स्वीकार करते हैं INT
और COLLATE
खंड उस संदर्भ में मान्य नहीं है (यही कारण है कि NCHAR()
केवल सप्लीमेंट्री कैरेक्टर का समर्थन करता है जब वर्तमान डेटाबेस में एक डिफ़ॉल्ट टकराव होता है जो सप्लीमेंट्री कैरेक्टर-अवेयर है; लेकिन यह एक अनावश्यक है असुविधा जिसे बदला जा सकता है, इसलिए कृपया मेरे सुझाव के लिए वोट करें:NCHAR () फ़ंक्शन को हमेशा मानों के लिए पूरक चरित्र लौटना चाहिए 0x10000 - 0x10FFFF सक्रिय डेटाबेस के डिफ़ॉल्ट टकराने की परवाह किए बिना )।
क्या इस बात की कोई व्याख्या है कि, टकराव की परवाह किए बिना, SQL सर्वर विस्तारित चरित्रों के परिप्रेक्ष्य से छोड़कर समझ सकता है और उनसे निपट सकता है NCHAR
?
SQL सर्वर डेटा अनुपूरक वर्णों को कैसे संग्रहीत और पुनर्प्राप्त कर सकता है, इस उत्तर के शीर्ष भाग में बताया गया था। लेकिन, यह सच नहीं है कि NCHAR
केवल एक अंतर्निहित फ़ंक्शन है जिसमें सप्लीमेंट्री कैरेक्टर (जब SCA Collas का उपयोग नहीं किया जाता है) के साथ समस्याएँ हैं। उदाहरण के लिए, LEN(N'😀' COLLATE SQL_Latin1_General_CP1_CI_AS)
2 का LEN(N'😀' COLLATE Latin1_General_100_CI_AS_SC)
मान लौटाता है जबकि 1 का मान लौटाता है।
यदि आप प्रश्न में पोस्ट किए गए दूसरे लिंक पर जाते हैं (अर्थात "Microsoft की पूरक वर्णक सूचनाएँ") और थोड़ा नीचे स्क्रॉल करें, तो आपको अंतर्निहित कार्यों का एक चार्ट दिखाई देगा और वे कैसे प्रभावी Collation के आधार पर व्यवहार करते हैं।
मुझे एक टकराव कैसे मिला जिसमें "पूरक चरित्र" ध्वज है?
2012 से पहले SQL सर्वर के किसी संस्करण में आप नहीं कर सकते। लेकिन, 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 सर्वर Collations (यानी जिनके साथ शुरू हो रहा है SQL_
) को कुछ समय के लिए Windows Collations (जिनके साथ शुरू नहीं हुआ SQL_
) के पक्ष में पदावनत किया गया है । इसलिए, SQL_
Collations को अपडेट नहीं किया जा रहा है और इसलिए उसके पास कोई नया संस्करण नहीं है, जिसमें _SC
विकल्प शामिल होगा (और SQL सर्वर 2017 में शुरू होने पर, सभी नए टकराव स्वचालित रूप से सप्लीमेंट्री कैरेक्टर का समर्थन करते हैं और ज़रूरत नहीं है, या _SC
झंडा, और हाँ, क्वेरी; _UTF8
एसक्यूएल सर्वर 2019 में जोड़े गए कोलाज को चुनने के साथ-साथ उस के लिए तुरंत ऊपर दिखाए गए )।
क्या आप पुराने इंस्टेंस पर कोलाज इंस्टॉल कर सकते हैं?
नहीं, आप SQL सर्वर के पिछले संस्करण में Collations स्थापित नहीं कर सकते।
मैं एक डेटाबेस में कोड (वास्तविक अनुपूरक चरित्र का उपयोग किए बिना) में एक अनुपूरक स्ट्रिंग चर (जैसे nvarchar) को एक डेटाबेस में कैसे सेट कर सकता हूं, जहां "संपूरक वर्ण (SC) ध्वज" समाहित नहीं करता है?
...
हालाँकि सर्वर SQL Server 2008 R2 है, मैं बाद के संस्करणों के लिए किसी भी समाधान के बारे में उत्सुक हूं।
SCA Collation का उपयोग नहीं करने पर, आप 65535 / U + FFFF से ऊपर कोड पॉइंट्स को दो तरीकों से इंजेक्ट कर सकते हैं:
NCHAR()
फ़ंक्शन के लिए दो कॉल के संदर्भ में सरोगेट जोड़ी निर्दिष्ट करें , प्रत्येक जोड़ी के एक भाग के साथ
VARBINARY
लिटिल एंडियन (यानी उलट) बाइट अनुक्रम के रूप में परिवर्तित करने के संदर्भ में सरोगेट जोड़ी को निर्दिष्ट करें ।
सप्लीमेंट्री कैरेक्टर / सरोगेट पेयर डालने के ये दो तरीके तब भी काम करेंगे, जब प्रभावी कॉलेमेंट सप्लीमेंट्री कैरेक्टर-अवेयर हो, और यह SQL सर्वर के सभी संस्करणों में समान रूप से काम करे, कम से कम 2005 तक वापस आ जाए (हालाँकि शायद यह भी काम करेगा SQL सर्वर 2000 भी)।
उदाहरण:
- चरित्र:
💩
- नाम: पू का ढेर
- दशमलव: 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)
अद्यतन करें
65536 - 1114111 (0x010000 - 0x10FFFF) के बीच किसी भी कोड पॉइंट से सरोगेट पेयर वैल्यू (दोनों INT
और BINARY
फॉर्म में) प्राप्त करने के लिए आप निम्न iTVF का उपयोग कर सकते हैं । और, जबकि इनपुट पैरामीटर प्रकार का है INT
, आप कोड पॉइंट के बाइनरी / हेक्स फॉर्म में पास कर सकते हैं और यह सही पूर्णांक मान में बदल जाएगा।
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 कोड पॉइंट वापस करने के लिए अनुकूलित किया है ताकि आपको इसे किसी विशेष मूल्य पर फिट करने की आवश्यकता न हो। बेशक, एक टीवीएफ होने के नाते, आप WHERE
किसी विशेष कोड बिंदु, या कोड बिंदुओं की श्रेणी, या "समान वर्ण", आदि पर फ़िल्टर करने के लिए एक खंड जोड़ सकते हैं और, इसमें प्रत्येक कोड के निर्माण के लिए पूर्व-स्वरूपित एस्केप अनुक्रम के साथ अतिरिक्त कॉलम शामिल हैं T-SQL, HTML, और C- शैली (यानी \xHHHH
) में बिंदु (BMP और पूरक वर्ण) दोनों । इसके बारे में सब कुछ यहां पढ़ें:
SSMS टिप # 3: आसानी से सभी यूनिकोड वर्ण तक पहुँच / अनुसंधान (हाँ, इमोजी सहित)