Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

използване на pyodbc на linux за вмъкване на уникод или utf-8 знаци в поле nvarchar mssql

Спомням си, че имах такъв вид глупави проблеми при използване на odbc драйвери, дори ако този път беше комбинация от java+oracle.

Основното нещо е, че odbc драйверът очевидно кодира низа на заявката, когато го изпраща към DB. Дори ако полето е Unicode и ако предоставите Unicode, в някои случаи това изглежда няма значение.

Трябва да се уверите, че изпратеното от драйвера има същото кодиране като вашата база данни (не само сървър, но и база данни). В противен случай, разбира се, получавате фънки знаци, защото или клиентът, или сървърът смесват нещата при кодиране/или декодиране. Имате ли представа за набора от знаци (кодовата точка, както MS обича да казва), който вашият сървър използва като стандартен за декодиране на данни?

Съпоставянето няма нищо общо с този проблем :)

Вижте тази MS страница например. За Unicode полета сортирането се използва само за определяне на реда на сортиране в колоната, не за да укажете как се съхраняват данните.

Ако съхранявате данните си като Unicode, има уникален начин да ги представите, това е целта на Unicode:няма нужда да дефинирате набор от знаци, който е съвместим с всички езици, които ще използвате :)

Въпросът тук е „какво се случва, когато дам данни на сървъра, които не са Unicode?". Например:

  • Когато изпратя UTF-8 низ към сървъра, как той го разбира?
  • Когато изпратя UTF-16 низ към сървъра, как той го разбира?
  • Когато изпратя низ от Latin1 на сървъра, как той го разбира?

От гледна точка на сървъра всички тези 3 низа са само поток от байтове. Сървърът не може да познае кодирането, в което сте ги кодирали. Което означава, че ще получавате проблеми, ако вашият odbc клиент изпрати байтови низове (кодиран низ) към сървъра, вместо да изпраща unicode данни:ако го направите, сървърът ще използва предварително дефинирано кодиране (това беше моят въпрос:какво кодиране ще използва сървърът? Тъй като не се предполага, трябва да е стойност на параметър) и ако низът е бил кодиран с помощта на различно кодиране, 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 може да изпраща директно данните като Unicode. Ако pyodbc не успее да направи това, ще получите неочаквани резултати.

И описах проблема по начина от клиент към сървър. Но същият вид проблеми могат да възникнат при обратна комуникация от сървъра към клиента. Ако клиентът не може да разбере Unicode данните, вероятно ще имате проблеми.

FreeTDS обработва Unicode вместо вас.

Всъщност FreeTDS се грижи за нещата вместо вас и превежда всички данни в UCS2 unicode. (Източник ).

  • Сървър <--> FreeTDS:UCS2 данни
  • FreeTDS <--> pyodbc:кодирани низове, кодирани в UTF-8 (от /etc/freetds/freetds.conf )

Така че очаквам вашето приложение да работи правилно, ако подадете UTF-8 данни към pyodbc. Всъщност, тъй като този django-pyodbc билет състояния, django-pyodbc комуникира в UTF-8 с pyodbc, така че трябва да сте добре.

FreeTDS 0.82

Въпреки това cramm0 казва, че FreeTDS 0.82 не е напълно без грешки и че има значителни разлики между 0.82 и официалната версия с корекция 0.82, която може да се намери тук . Вероятно трябва да опитате да използвате пакетирания FreeTDS

Редактирано :премахнати стари данни, които нямаха нищо общо с FreeTDS, но бяха приложими само за комерсиалния odbc драйвер на Easysoft. Съжалявам.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Преобразуване на „01-Sep-2017“ в „01/09/2017“ в T-SQL?

  2. Как OBJECTPROPERTYEX() работи в SQL Server

  3. Сравнението на низове е неуспешно с променлива varchar

  4. Задайте публичен профил по подразбиране за поща от база данни (SSMS)

  5. Защо съхранената процедура е по-бърза от Query