कैसे एक "चरित्र" (जिसमें कई कोड पॉइंट शामिल हो सकते हैं: एक दूसरे से तुलना करने वाले जोड़े, पात्रों का संयोजन, सरोगेट करें) नियमों के बजाय जटिल सेट पर आधारित है। यूनिकोड विनिर्देशन में दर्शाई गई सभी भाषाओं में पाए जाने वाले सभी विभिन्न (और कभी-कभी "निराला") नियमों की आवश्यकता के कारण यह बहुत जटिल है । यह प्रणाली सभी NVARCHAR
डेटा के लिए गैर-बाइनरी Collations पर लागू होती है , और VARCHAR
डेटा के लिए जो Windows Collation का उपयोग कर रहा है और SQL सर्वर Collation (एक के साथ शुरू होने वाला SQL_
) नहीं। यह सिस्टम VARCHAR
SQL सर्वर Collation का उपयोग करने वाले डेटा पर लागू नहीं होता है क्योंकि वे साधारण मैपिंग का उपयोग करते हैं।
अधिकांश नियमों को यूनिकोड कॉलेशन एल्गोरिथ्म (UCA) में परिभाषित किया गया है । उन नियमों में से कुछ, और कुछ यूसीए में शामिल नहीं हैं:
allkeys.txt
फ़ाइल में दिया गया डिफ़ॉल्ट ऑर्डर / वजन (नीचे दिया गया)
- कौन सी संवेदनशीलता और विकल्पों का उपयोग किया जा रहा है (जैसे कि यह संवेदनशील या असंवेदनशील है ?, और यदि संवेदनशील है, तो क्या यह ऊपरी-मामला पहले या निचले मामले में है?)
- कोई भी स्थानीय-आधारित ओवरराइड।
- यूनिकोड मानक के संस्करण का उपयोग किया जा रहा है।
- "मानव" कारक (यानी यूनिकोड एक विनिर्देश है, सॉफ्टवेयर नहीं है, और इस प्रकार इसे लागू करने के लिए प्रत्येक विक्रेता पर छोड़ दिया जाता है)
मैंने मानव कारक के बारे में अंतिम बिंदु पर जोर देकर स्पष्ट रूप से यह स्पष्ट करने के लिए कहा कि किसी को SQL सर्वर से हमेशा विनिर्देश के अनुसार 100% व्यवहार करने की उम्मीद नहीं करनी चाहिए।
यहां ओवरराइडिंग कारक प्रत्येक कोड पॉइंट को दिया गया वेटिंग है, और यह तथ्य कि मल्टीपल कोड पॉइंट्स एक ही वेट स्पेसिफिकेशन साझा कर सकते हैं। आप यहां बुनियादी भार (कोई स्थानीय-विशिष्ट ओवरराइड नहीं) पा सकते हैं (मेरा मानना है कि 100
Collations की श्रृंखला यूनिकोड v 5.0 है - Microsoft कनेक्ट आइटम पर टिप्पणियों में अनौपचारिक पुष्टि ):
http://www.unicode.org/Public/UCA/5.0.0/allkeys.txt
प्रश्न में कोड बिंदु - U + FFFD - के रूप में परिभाषित किया गया है:
FFFD ; [*0F12.0020.0002.FFFD] # REPLACEMENT CHARACTER
यह संकेतन UCA के खंड 9.1 Allkeys फ़ाइल प्रारूप में परिभाषित किया गया है :
<entry> := <charList> ';' <collElement>+ <eol>
<charList> := <char>+
<collElement> := "[" <alt> <weight> "." <weight> "." <weight> ("." <weight>)? "]"
<alt> := "*" | "."
Collation elements marked with a "*" are variable.
यह अंतिम पंक्ति महत्वपूर्ण है क्योंकि हम जिस कोड बिंदु को देख रहे हैं उसमें एक विनिर्देश है जो वास्तव में "*" से शुरू होता है। खंड 3.6 परिवर्तनीय भार में Collation कॉन्फ़िगरेशन मूल्यों के आधार पर चार संभावित व्यवहार परिभाषित हैं, जिनकी हमारे पास कोई सीधी पहुंच नहीं है (ये प्रत्येक Collation के Microsoft कार्यान्वयन में हार्ड-कोडित हैं, जैसे कि केस-संवेदी पहले लो-केस का उपयोग करता है या ऊपरी-मामला पहले, एक संपत्ति जो Collations और अन्य सभी विविधताओं VARCHAR
का उपयोग कर डेटा के बीच अलग है SQL_
)।
मेरे पास यह पूर्ण शोध करने का समय नहीं है कि कौन से रास्ते लिए गए हैं और यह पता लगाने के लिए कि कौन से विकल्प का उपयोग किया जा रहा है ताकि अधिक ठोस प्रमाण दिया जा सके, लेकिन यह कहना सुरक्षित है कि प्रत्येक कोड पॉइंट विनिर्देश में, कुछ है या नहीं माना जाता है कि "बराबर" हमेशा पूर्ण विनिर्देशन का उपयोग करने वाला नहीं है। इस मामले में, हमारे पास "0F12.0020.0002.FFFD" है और सबसे अधिक संभावना है कि यह केवल स्तर 2 और 3 है जिसका उपयोग किया जा रहा है (यानी ।0020.0002। )। ".0020.0002" के लिए नोटपैड ++ में "काउंट" करें। 12,581 मैच (पूरक चरित्रों के साथ, जिन्हें हम अभी तक नहीं निभा रहे हैं) खोजता है। "[*" पर "काउंट" करने से 4049 मैच लौटते हैं। एक RegEx करना "ढूंढें" / "गणना करें" के पैटर्न का उपयोग करना\[\*\d{4}\.0020\.0002
832 मैच जीते। तो इस संयोजन में कहीं और, संभवतः कुछ अन्य नियम जो मैं नहीं देख रहा हूं, साथ ही कुछ Microsoft-विशिष्ट कार्यान्वयन विवरण, इस व्यवहार का पूर्ण विवरण है। और स्पष्ट होने के लिए, सभी मिलान वाले पात्रों के लिए व्यवहार समान है क्योंकि वे सभी एक दूसरे से मेल खाते हैं क्योंकि नियमों को लागू करने के बाद वे सभी का वजन समान होता है (मतलब, यह प्रश्न उनमें से किसी एक के बारे में पूछा जा सकता है, नहीं जरूरी श्री �
)।
आप नीचे दिए गए क्वेरी के साथ देख सकते हैं और COLLATE
क्लॉज को परिणामों के अनुसार क्लॉज में बदल सकते हैं कि कैसे विभिन्न संवेदनाएं Collations के दो संस्करणों में काम करती हैं:
;WITH cte AS
(
SELECT TOP (65536) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1 AS [Num]
FROM [master].sys.columns col
CROSS JOIN [master].sys.objects obj
)
SELECT cte.Num AS [Decimal],
CONVERT(VARBINARY(2), cte.Num) AS [Hex],
NCHAR(cte.Num) AS [Character]
FROM cte
WHERE NCHAR(cte.Num) = NCHAR(0xFFFD) COLLATE Latin1_General_100_CS_AS_WS --N'�'
ORDER BY cte.Num;
विभिन्न कोलाज में मिलान वाले पात्रों की विभिन्न गणना नीचे है।
Latin1_General_100_CS_AS_WS = 5840
Latin1_General_100_CS_AS = 5841 (The "extra" character is U+3000)
Latin1_General_100_CI_AS = 5841
Latin1_General_100_CI_AI = 6311
Latin1_General_CS_AS_WS = 21,229
Latin1_General_CS_AS = 21,230
Latin1_General_CI_AS = 21,230
Latin1_General_CI_AI = 21,537
ऊपर सूचीबद्ध सभी संप्रत्ययों में N'' = N'�'
भी सत्य का मूल्यांकन होता है।
अपडेट करें
मैं थोड़ा और शोध करने में सक्षम था और यहाँ मैंने पाया:
यह "शायद" कैसे काम करना चाहिए
ICU Collation Demo का उपयोग करते हुए , मैंने "en-US-u-va-posix" को लोकेल सेट किया, "प्राइमरी", चेक शो "सॉर्ट कीज़" की स्ट्रेंथ सेट की, और निम्न 4 वर्णों में पेस्ट किया, जिन्हें मैंने कॉपी किया था उपरोक्त क्वेरी के परिणाम ( Latin1_General_100_CI_AI
कॉलेशन का उपयोग करते हुए ):
�
Ԩ
ԩ
Ԫ
और वह रिटर्न:
Ԫ
60 2E 02 .
Ԩ
60 7A .
ԩ
60 7A .
�
FF FD .
फिर, http://unicode.org/cldr/utility/character.jsp?a=fffd पर " " के लिए वर्ण गुणों की जाँच करें और देखें कि स्तर 1 सॉर्ट कुंजी (यानी FF FD
) "uca" संपत्ति से मेल खाती है। उस "uca" पर क्लिक करने पर संपत्ति आपको एक खोज पृष्ठ पर ले जाती है - http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3Auca%3DFFFD%3A%DD - जो सिर्फ 1 मैच दिखा रहा है। और, allkeys.txt फ़ाइल में, स्तर 1 प्रकार का वजन दिखाया गया है 0F12
, और उसके लिए केवल 1 मैच है।
यह सुनिश्चित करने के लिए कि हम व्यवहार को सही ढंग से व्याख्या कर रहे हैं, मैंने एक और चरित्र को देखा: GREEK CAPETET LETTER OMICRON with VARIA Ὸ
at http://unicode.org/cldr/utility/character.jsp?a=1808 जिस पर "uca" (है) यानी के स्तर 1 प्रकार वजन / संपार्श्विक तत्व) 5F30
। उस "5F30" पर क्लिक करने से हमें एक खोज पृष्ठ पर ले जाता है - http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3Auca%3D5F30%3A%DD - 30 मैच दिखा रहा है, 20 बार उन्हें 0 - 65535 रेंज (यानी U + 0000 - U + FFFF) में रखा गया है। Codekey 1FF8 के लिए allkeys.txt फ़ाइल में देखते हुए , हम एक स्तर 1 का वजन देखते हैं 12E0
। नोटपैड ++ में एक "काउंट" कर रहा है12E0.
30 मैच दिखाता है (यह यूनिकोड से परिणाम से मेल खाता है। हालांकि यह गारंटी नहीं है क्योंकि फ़ाइल यूनिकोड v 5.0 के लिए है और साइट यूनिकोड v 9.0 डेटा का उपयोग कर रही है)।
SQL सर्वर में, निम्न क्वेरी 20 मैच लौटाती है, जैसे कि यूनिकोड.ऑर्ग खोज 10 पूरक वर्ण हटाते समय:
;WITH cte AS
(
SELECT TOP (65535) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [Num]
FROM [master].sys.columns col
CROSS JOIN [master].sys.objects obj
)
SELECT cte.Num AS [Decimal],
CONVERT(VARCHAR(50), CONVERT(VARBINARY(2), cte.Num), 2) AS [Hex],
NCHAR(cte.Num) AS [Character]
FROM cte
WHERE NCHAR(cte.Num) = NCHAR(0x1FF8) COLLATE Latin1_General_100_CI_AI
ORDER BY cte.Num;
और, बस सुनिश्चित करें, ICU Collation डेमो पेज पर वापस जा रहा है, और SQL सर्वर से 20 परिणामों की सूची से लिए गए निम्नलिखित 3 वर्णों के साथ "इनपुट" बॉक्स में वर्णों की जगह ले रहा है:
Ὂ
𝜪
Ὸ
दिखाता है कि वे, वास्तव में, सभी का समान 5F 30
स्तर 1 प्रकार का वजन है (चरित्र संपत्ति पृष्ठ पर "ओका" फ़ील्ड से मेल खाता है)।
एसओ, यह निश्चित रूप से ऐसा लगता है जैसे कि यह विशेष चरित्र कुछ और से मेल नहीं खाना चाहिए ।
यह वास्तव में कैसे काम करता है (कम से कम Microsoft-भूमि में)
SQL सर्वर के विपरीत, .NET के पास एक स्ट्रिंग के लिए SortInfo.GetSortKey विधि के माध्यम से सॉर्ट कुंजी दिखाने का एक साधन है । इस पद्धति का उपयोग करके और केवल U + FFFD वर्ण में पास होने के बाद, यह एक प्रकार की कुंजी देता है 0x0101010100
। फिर, 0 - 65535 की सीमा में सभी पात्रों पर पुनरावृत्ति करते हुए यह देखने के लिए कि उनमें से 0x0101010100
किसके पास 4529 मैचों की वापसी की कुंजी है । यह SQL सर्वर में लौटे 5840 से बिलकुल भी मेल नहीं खाता (जब Latin1_General_100_CS_AS_WS
Collation का उपयोग करते हुए ), लेकिन यह निकटतम है जिसे हम (अभी के लिए) प्राप्त कर सकते हैं, यह देखते हुए कि मैं विंडोज 10 और .NET फ्रेमवर्क संस्करण 4.6.1 चला रहा हूं, जिसमें यूनिकोड v का उपयोग किया गया है चार्ट के अनुसार चार्ट के अनुसार 6.3.0 चार्यूनिकोडइन्फो क्लास के लिए("नोट टू कॉलर्स", "रिमार्क्स" अनुभाग में)। फिलहाल मैं SQLCLR फ़ंक्शन का उपयोग कर रहा हूं और इसलिए लक्ष्य फ्रेमवर्क संस्करण को बदल नहीं सकता। जब मुझे मौका मिलता है तो मैं एक कंसोल ऐप बनाऊंगा और 4.5 के टारगेट फ्रेमवर्क संस्करण का उपयोग करूंगा क्योंकि यह यूनिकोड वी 5.0 का उपयोग करता है, जिसे 100 सीरीज़ कोलाज़ से मेल खाना चाहिए।
कि क्या इस परीक्षण से पता चलता है है, यहां तक कि नेट और U + FFFD के लिए एसक्यूएल सर्वर के बीच मैचों की सटीक एक ही नंबर के बिना, यह बहुत स्पष्ट है कि इस है नहीं एसक्यूएल सर्वर-विशिष्ट व्यवहार, और जानबूझकर या कार्यान्वयन के साथ निरीक्षण किया है कि क्या Microsoft द्वारा, U + FFFD चरित्र वास्तव में काफी कुछ वर्णों से मेल खाता है, भले ही यह यूनिकोड विनिर्देश के अनुसार न हो। और, यह देखते हुए कि यह चरित्र U + 0000 (अशक्त) से मेल खाता है, यह शायद केवल गायब वज़न का मुद्दा है।
भी
=
क्वेरी बनाम व्यवहार में अंतर के बारे में LIKE N'%�%'
, इसे वाइल्डकार्ड और इन (यानी � Ƕ Ƿ Ǹ
) वर्णों के लिए अनुपलब्ध (मुझे लगता है) भार के साथ करना है । यदि LIKE
स्थिति को बस में बदला जा रहा है LIKE N'�'
तो यह =
स्थिति के समान 3 पंक्तियों को लौटाता है । यदि वाइल्डकार्ड के साथ समस्या "गायब" वज़न के कारण नहीं है ( btw 0x00
द्वारा किसी प्रकार की कुंजी नहीं दी गई है CompareInfo.GetSortKey
), तो यह इन वर्णों के कारण हो सकता है संभवतः एक संपत्ति है जो संदर्भ के आधार पर सॉर्ट कुंजी को अलग-अलग करने की अनुमति देती है (अर्थात आसपास के वर्ण) )।
FFFD
(*0F12.0020.0002.FFFD
केवल एक परिणाम की खोज)। @ फॉरेस्ट के अवलोकन से कि वे सभी रिक्त स्ट्रिंग से मेल खाते हैं और इस विषय पर थोड़ा और अधिक पढ़ने से ऐसा लगता है कि विभिन्न गैर बाइनरी कॉलेक्शन में उनके द्वारा साझा किए गए वजन वास्तव में शून्य है जो मुझे विश्वास है।