Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

एक nvarchar mssql क्षेत्र में यूनिकोड या utf-8 वर्ण सम्मिलित करने के लिए linux पर pyodbc का उपयोग करना

मुझे याद है कि ओडीबीसी ड्राइवरों का उपयोग करते हुए इस तरह की बेवकूफी भरी समस्याएं थीं, भले ही उस समय यह एक जावा + ऑरेकल संयोजन था।

मुख्य बात यह है कि ओडीबीसी चालक स्पष्ट रूप से डीबी को भेजते समय क्वेरी स्ट्रिंग को एन्कोड करता है। भले ही फ़ील्ड यूनिकोड है, और यदि आप यूनिकोड प्रदान करते हैं, तो कुछ मामलों में यह मायने नहीं रखता है।

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

संयोजन का इस समस्या से कोई लेना-देना नहीं है :)

देखें वह MS पेज उदाहरण के लिए। यूनिकोड फ़ील्ड के लिए, कॉलेशन का उपयोग केवल कॉलम में सॉर्ट क्रम को परिभाषित करने के लिए किया जाता है, नहीं यह निर्दिष्ट करने के लिए कि डेटा कैसे संग्रहीत किया जाता है।

यदि आप अपना डेटा यूनिकोड के रूप में संग्रहीत करते हैं, तो इसका प्रतिनिधित्व करने का एक अनूठा तरीका है, यही यूनिकोड का उद्देश्य है:एक ऐसे वर्णसेट को परिभाषित करने की कोई आवश्यकता नहीं है जो उन सभी भाषाओं के अनुकूल हो जिनका आप उपयोग करने जा रहे हैं :)

यहां सवाल यह है कि "क्या होता है जब मैं सर्वर को डेटा देता हूं जो नहीं है यूनिकोड?". उदाहरण के लिए:

  • जब मैं सर्वर को UTF-8 स्ट्रिंग भेजता हूं, तो वह इसे कैसे समझता है?
  • जब मैं सर्वर को UTF-16 स्ट्रिंग भेजता हूं, तो वह इसे कैसे समझता है?
  • जब मैं सर्वर को एक लैटिन1 स्ट्रिंग भेजता हूं, तो वह इसे कैसे समझता है?

सर्वर के दृष्टिकोण से, ये सभी 3 तार केवल बाइट्स की एक धारा हैं। सर्वर उस एन्कोडिंग का अनुमान नहीं लगा सकता जिसमें आपने उन्हें एन्कोड किया था। जिसका अर्थ है कि आप करेंगे यदि आपका odbc क्लाइंट बाइटस्ट्रिंग्स भेज रहा है, तो समस्याएँ प्राप्त करें (एक एन्कोडेड स्ट्रिंग) यूनिकोड . भेजने के बजाय सर्वर पर डेटा:यदि आप ऐसा करते हैं, तो सर्वर एक पूर्वनिर्धारित एन्कोडिंग का उपयोग करेगा (यह मेरा प्रश्न था:सर्वर किस एन्कोडिंग का उपयोग करेगा? चूंकि यह अनुमान नहीं लगा रहा है, यह एक पैरामीटर मान होना चाहिए), और यदि स्ट्रिंग को एक का उपयोग करके एन्कोड किया गया था अलग एन्कोडिंग, dzing , डेटा दूषित हो जाएगा।

यह बिल्कुल Python में करने जैसा ही है:

uni = u'Hey my name is André'
in_utf8 = uni.encode('utf-8')
# send the utf-8 data to server
# send(in_utf8)

# on server side
# server receives it. But server is Japanese.
# So the server treats the data with the National charset, shift-jis:
some_string = in_utf8 # some_string = receive()    
decoded = some_string.decode('sjis')

बस इसे आजमा के देखो। मजा आता है। डिकोडेड स्ट्रिंग को "हे माई नेम इज आंद्रे" माना जाता है, लेकिन "हे माई नेम इज एंड्रू" है। é जापानी द्वारा प्रतिस्थापित हो जाता है テゥ

इसलिए मेरा सुझाव:आपको यह सुनिश्चित करने की ज़रूरत है कि pyodbc सीधे डेटा को यूनिकोड के रूप में भेजने में सक्षम है। यदि pyodbc ऐसा करने में विफल रहता है, तो आपको अप्रत्याशित परिणाम मिलेंगे।

और मैंने क्लाइंट से सर्वर तरीके से समस्या का वर्णन किया। लेकिन सर्वर से क्लाइंट तक वापस संचार करते समय उसी तरह की समस्याएं उत्पन्न हो सकती हैं। यदि क्लाइंट यूनिकोड डेटा को नहीं समझ सकता है, तो आप मुश्किल में पड़ सकते हैं।

FreeTDS आपके लिए यूनिकोड संभालता है।

दरअसल, FreeTDS आपके लिए चीजों का ख्याल रखता है और सभी डेटा को UCS2 यूनिकोड में ट्रांसलेट करता है। (स्रोत )।

  • सर्वर <--> FreeTDS :UCS2 डेटा
  • FreeTDS <--> pyodbc :एन्कोडेड स्ट्रिंग्स, UTF-8 में एन्कोडेड (/etc/freetds/freetds.conf से) )

इसलिए यदि आप UTF-8 डेटा को pyodbc पर पास करते हैं, तो मैं आपके आवेदन से सही ढंग से काम करने की अपेक्षा करता हूँ। दरअसल, यह django-pyodbc टिकट है राज्य, django-pyodbc UTF-8 में pyodbc के साथ संचार करता है, इसलिए आपको ठीक होना चाहिए।

फ्रीटीडीएस 0.82

हालांकि, cram0 का कहना है कि FreeTDS 0.82 पूरी तरह से बग-मुक्त नहीं है, और यह कि 0.82 और आधिकारिक पैच किए गए 0.82 संस्करण के बीच महत्वपूर्ण अंतर हैं जिन्हें पाया जा सकता है यहां . आपको शायद पैच किए गए FreeTDS का उपयोग करने का प्रयास करना चाहिए

संपादित :पुराने डेटा को हटा दिया, जिसका फ्रीटीडीएस से कोई लेना-देना नहीं था, लेकिन केवल ईज़ीसॉफ्ट कमर्शियल ओडीबीसी ड्राइवर के लिए प्रासंगिक था। क्षमा करें।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एसक्यूएल में मेरे डेटाटाइम फ़ील्ड से केवल समय अपडेट करें

  2. वास्तविक दुनिया की समस्याओं को हल करने के लिए सरल SQL सर्वर कार्य

  3. SQL सर्वर में "अंकगणित अतिप्रवाह त्रुटि को डेटा प्रकार संख्यात्मक में परिवर्तित करना" को ठीक करें

  4. SQL सर्वर डेटाबेस में सभी तालिकाओं से सभी प्राथमिक कुंजियों को कैसे छोड़ें - SQL सर्वर / TSQL ट्यूटोरियल भाग 65

  5. बीसीपी/बल्क इंसर्ट बनाम टेबल-वैल्यूड पैरामीटर्स का प्रदर्शन