मैं SQL सर्वर यूनिकोड / NVARCHAR स्ट्रिंग को इमोजी या सप्लीमेंट्री कैरेक्टर में कैसे सेट करूँ?


23

मैं अपने यूनिकोड कोड बिंदु के आधार पर विशेष वर्ण के लिए एक यूनिकोड स्ट्रिंग चर सेट करना चाहता हूं।

मैं 65535 से परे एक कोड बिंदु का उपयोग करना चाहता हूं, लेकिन SQL Server 2008 R2 डेटाबेस का एक टकराव है SQL_Latin1_General_CP1_CI_AS

Microsoft के NCHAR प्रलेखन के अनुसार , NCHARफ़ंक्शन एक पूर्णांक को निम्नानुसार लेता है:

integer_expression

जब डेटाबेस के टकराव में पूरक चरित्र (एससी) ध्वज नहीं होता है, तो यह 65535 (0xFFFF के माध्यम से) के माध्यम से 0 से एक सकारात्मक पूरी संख्या है। यदि इस श्रेणी के बाहर का कोई मान निर्दिष्ट है, तो NULL लौटाया जाता है। पूरक वर्णों के बारे में अधिक जानकारी के लिए, Collation और Unicode समर्थन देखें।

जब डेटाबेस का टकराव पूरक चरित्र (SC) ध्वज का समर्थन करता है, तो यह 1114111 (0 से 0x10FFFF) के माध्यम से 0 से एक सकारात्मक पूर्ण संख्या है। यदि इस श्रेणी के बाहर का कोई मान निर्दिष्ट है, तो NULL लौटाया जाता है।

तो यह कोड:

SELECT NCHAR(128512);

NULLइस डेटाबेस में वापस आता है।

मैं चाहूंगा कि इसे इस प्रकार लौटाया जाए:

SELECT N'😀';

मैं एक डेटाबेस में कोड का उपयोग करके (वास्तविक इमोजी चरित्र का उपयोग किए बिना) इमोजी को एक यूनिकोड स्ट्रिंग चर (जैसे nvarchar) कैसे सेट कर सकता हूं, जहां "" पूरक चरित्र (SC) ध्वज शामिल नहीं है?

इमोजी यूनिकोड कोड बिंदुओं की पूरी सूची

(अंत में मैं चाहता हूं कि कोई भी किरदार काम करे। मैंने सिर्फ संदर्भ के लिए इमोजी को चुना।)

(हालांकि सर्वर SQL Server 2008 R2 है, मैं बाद के संस्करणों के लिए किसी भी समाधान के बारे में उत्सुक हूं।)

यह मानते हुए कि कोई रास्ता नहीं है, क्या मैं एक अन्य डेटाबेस में एक इनलाइन उपयोगकर्ता-परिभाषित फ़ंक्शन का संदर्भ दे सकता हूं जिसमें एक उपयुक्त टकराव था?

मुझे एक टकराव कैसे मिला जिसमें "पूरक चरित्र" ध्वज है?

यह हमारे सर्वर पर कोई रिकॉर्ड नहीं देता है:

SELECT * FROM sys.fn_helpcollations() 
WHERE name LIKE 'SQL%[_]SC';

यह SQL Server 2012 की तरह लगता है Latin1_General_100_CI_AS_SCजो काम करेगा। क्या आप पुराने इंस्टेंस पर कोलाज इंस्टॉल कर सकते हैं?

टकराव संदर्भ:

क्या इस बात की कोई व्याख्या है कि, टकराव की परवाह किए बिना, SQL सर्वर विस्तारित चरित्रों के परिप्रेक्ष्य से छोड़कर समझ सकता है और उनसे निपट सकता है NCHAR?


व्यापक अतिरिक्त जानकारी के लिए धन्यवाद। मैं अब इस मुद्दे का सामना नहीं कर रहा हूं, लेकिन मैं इस जानकारी को मानसिक रूप से बुकमार्क रखूंगा।
रिले मेजर

1
कोई बात नहीं। मुझे नहीं लगता था तुम अब भी कर रहे थे की आवश्यकता होगी, कुछ, सिर्फ इतना है कि आप की सराहना करते हैं सकता है / अनुकूलन का उपयोग करने के लिए सक्षम हो ...
सोलोमन Rutzky

जवाबों:


36

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 रेंज से परे वर्णों का प्रतिनिधित्व करते हैं जिन्हें पूरक वर्ण के रूप में जाना जाता है।

सभी जानकारी NVARCHARSQL सर्वर में / यूनिकोड डेटा के दो पहलुओं की व्याख्या करती है :

  1. कई अंतर्निहित कार्य (सिर्फ नहीं NCHAR()) एक सप्लीमेंट्री कैरेक्टर-एवेयर Collation (SCA; यानी एक के साथ _SC, या नाम में _140_नहीं _BIN*) का उपयोग न करने पर सरोगेट पेयर / सप्लीमेंट्री कैरेक्टर को हैंडल नहीं करते हैं क्योंकि नॉन-एससीएल कोलाइज़ेशन (विशेष रूप से) SQL_Collations) मूल रूप से UTF-16 के पूरा होने से पहले लागू किया गया था (2000 में, मुझे विश्वास है)। गैर- SQL_टकराव, जिनके पास _90_या _100_उनके नाम हैं लेकिन _SCतुलना और छँटाई के मामले में पूरक वर्णों के लिए न्यूनतम समर्थन नहीं है।
  2. पूर्ण यूनिकोड / 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 से ऊपर कोड पॉइंट्स को दो तरीकों से इंजेक्ट कर सकते हैं:

  1. NCHAR()फ़ंक्शन के लिए दो कॉल के संदर्भ में सरोगेट जोड़ी निर्दिष्ट करें , प्रत्येक जोड़ी के एक भाग के साथ
  2. 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: आसानी से सभी यूनिकोड वर्ण तक पहुँच / अनुसंधान (हाँ, इमोजी सहित)


1
महान काम सोलोमन! बहुत बढ़िया स्पष्टीकरण
रॉनन एरेली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.