@ लोगों ने पहले ही मूल कारण और तय कर दिया था, लेकिन जो व्यवहार आप देख रहे हैं उसका विशिष्ट कारण यह है:
- आप
VARCHAR
शाब्दिक ( N
उपसर्ग के NVARCHAR
साथ स्ट्रिंग ) के बजाय एक शाब्दिक (कोई उपसर्ग) का उपयोग कर रहे हैं N
, इसलिए यूनिकोड वर्ण में परिवर्तित हो जाएगा VARCHAR
।
VARCHAR
एक 8-बिट एन्कोडिंग है, जो ज्यादातर मामलों में, प्रति वर्ण एक बाइट है, लेकिन प्रति चरित्र दो बाइट्स भी हो सकता है। दूसरी ओर, NVARCHAR
16-बिट एन्कोडिंग (UTF-16 लिटिल एंडियन) है जो कि प्रति वर्ण दो बाइट्स या चार बाइट्स है।
- मैपिंग वर्णों के लिए उपयोग करने के लिए उपलब्ध बाइट्स की संख्या में अंतर के कारण, 8 बिट एन्कोडिंग, उनके स्वभाव से, मैप किए जा सकने वाले वर्णों की संख्या में बहुत अधिक सीमित हैं।
VARCHAR
सिंगल-बाइट कैरेक्टर सेट्स (उनमें से अधिकांश) के लिए 256 वर्णों तक और डबल-बाइट कैरेक्टर सेट्स (इनमें से केवल कुछ) के लिए 65,536 वर्णों तक का डेटा है। दूसरी ओर, NVARCHAR
डेटा सिर्फ 1.1 मिलियन यूनिकोड वर्णों (हालांकि अभी 250k अंडर मैप्ड है) पर मैप कर सकता है।
- 8-बिट /
VARCHAR
डेटा के साथ किए जा सकने वाले मैपिंग की सीमित संख्या के कारण , वर्णों के विभिन्न समूह (भाषा / संस्कृति के आधार पर) एकाधिक "कोड पेज" (अर्थात वर्ण सेट) में फैले हुए हैं
- प्रत्येक Collation निर्दिष्ट करता है कि
VARCHAR
डेटा के लिए कौन सा कोड पृष्ठ, यदि कोई हो, ( NVARCHAR
सभी वर्ण है)
- स्ट्रिंग स्ट्रिंग शाब्दिक या चर
NVARCHAR
(यानी यूनिकोड / यूटीएफ -16 / सभी वर्ण) को VARCHAR
(कोड पृष्ठ पर आधारित वर्ण सेट जो कि अधिकांश कोलाज़ों में निर्दिष्ट है ) से परिवर्तित करते समय , डेटाबेस के डिफ़ॉल्ट Collation का उपयोग किया जाता है
- यदि रूपांतरण के लिए उपयोग किए जा रहे Collation के कोड पृष्ठ में समान वर्ण नहीं है, लेकिन इसमें "सर्वश्रेष्ठ फिट" मैपिंग है, तो "सर्वश्रेष्ठ फ़िट" मैपिंग का उपयोग किया जाएगा।
- यदि रूपांतरण के लिए उपयोग किए जा रहे Collation के कोड पृष्ठ में समान वर्ण नहीं है या "सर्वश्रेष्ठ फिट" मैपिंग है, तो डिफ़ॉल्ट "प्रतिस्थापन" वर्ण का उपयोग किया जाएगा (सबसे अधिक
?
)।
तो, क्या आप देख रहे हैं एक है NVARCHAR
करने के लिए VARCHAR
कारण लापता करने के लिए रूपांतरण N
स्ट्रिंग शाब्दिक पर उपसर्ग। और, डेटाबेस के लिए डिफ़ॉल्ट Collation के कोड पृष्ठ में सटीक समान वर्ण शामिल नहीं है, लेकिन एक "सर्वश्रेष्ठ फिट" मैपिंग पाई गई, यही वजह है कि आपको 2
इसके बजाय मिल रहा है ?
।
आप निम्नलिखित सरल परीक्षण करके इस आशय को देख सकते हैं:
SELECT '₂', N'₂';
यह दिखाता है:
2 ₂
स्पष्ट होने के लिए, डेटाबेस के लिए डिफ़ॉल्ट कॉलेशन के कोड पृष्ठ में सटीक समान वर्ण होता है, तो यह उस कोड पृष्ठ में उसी वर्ण में अनुवादित होता। और, फिर, आपके मामले में, चूंकि आप एक NVARCHAR
कॉलम में संग्रहित कर रहे हैं , इसलिए इसका अनुवाद फिर से मूल यूनिकोड वर्ण में होगा। नीचे दिया गया अंतिम उदाहरण इस व्यवहार को दर्शाता है।
महत्वपूर्ण: कृपया ध्यान रखें कि रूपांतरण तब होता है जब स्ट्रिंग शाब्दिक व्याख्या की जा रही है, जो कि कॉलम में संग्रहीत होने से पहले है। इसका मतलब यह है कि भले ही कॉलम उस चरित्र को पकड़ सकता है, यह पहले से ही कुछ और में बदल गया होगा, डेटाबेस के डिफ़ॉल्ट Collation के आधार पर, सभी N
उस स्ट्रिंग शाब्दिक पर उपसर्ग को छोड़ने के कारण । और यह वही है जो आप अनुभव कर रहे हैं (या थे)।
उदाहरण के लिए, यदि आपके डेटाबेस का डिफ़ॉल्ट Collation कोरियाई Collations (चार डबल-बाइट कैरेक्टर सेट्स में से एक) में से एक होता, तो आपको यह समस्या नहीं दिखाई देती क्योंकि "Subscript 2" का चरित्र उस वर्ण में उपलब्ध होता है सेट (कोड पृष्ठ ९ ४ ९)। देखने के लिए निम्न परीक्षण का प्रयास करें (यह डेटाबेस के डिफ़ॉल्ट Collation के बजाय कॉलम के Collation का उपयोग करता है क्योंकि यह दिखाना आसान है):
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 ₂ ₂
जैसा कि आप देख सकते हैं, डेटा के Modern_Spanish
लिए कोड 1, 1251 (समान कोड पेज जिसका उपयोग कोलाज़ उपयोग करता है) में लैटिन 1_जनरल कोलाजेशन, VARCHAR
एक सटीक मिलान नहीं है, लेकिन उनके पास "सबसे अच्छा फिट" मैपिंग है (जो आप देख रहे हैं। )। BUT, कोरियाई Collations, जो VARCHAR
डेटा के लिए कोड पृष्ठ 949 का उपयोग करते हैं, का "Subscript 2" वर्ण के लिए सटीक मिलान है।
आगे वर्णन करने के लिए, हम एक कोरियाई Collations के डिफ़ॉल्ट Collation के साथ एक नया डेटाबेस बना सकते हैं, और फिर उस प्रश्न में सटीक 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₂
अपडेट करें
जो लोग वास्तव में यहाँ क्या हो रहा है (यानी सभी विवरण के बारे में अधिक जानकारी प्राप्त करने में रुचि रखते हैं ) के लिए, कृपया मेरे द्वारा पोस्ट की गई दो-भाग की जांच देखें: