Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

używanie pyodbc na Linuksie do wstawiania znaków Unicode lub UTF-8 w polu nvarchar mssql

Pamiętam, że miałem tego rodzaju głupie problemy ze sterownikami odbc, nawet jeśli w tamtym czasie była to kombinacja java + Oracle.

Najważniejszą rzeczą jest to, że sterownik odbc najwyraźniej koduje ciąg zapytania podczas wysyłania go do bazy danych. Nawet jeśli pole to Unicode i jeśli podasz Unicode, w niektórych przypadkach wydaje się to nie mieć znaczenia.

Musisz upewnić się, że to, co jest wysyłane przez sterownik, ma takie samo kodowanie jak Twoja baza danych (nie tylko serwer, ale także baza danych). W przeciwnym razie, oczywiście otrzymasz dziwne znaki, ponieważ albo klient, albo serwer mieszają rzeczy podczas kodowania/dekodowania. Czy masz pojęcie o zestawie znaków (punkt kodowy, jak mawia MS), którego serwer używa domyślnie do dekodowania danych?

Sortowanie nie ma nic wspólnego z tym problemem :)

Zobacz tę stronę MS na przykład. W przypadku pól Unicode sortowanie służy tylko do zdefiniowania kolejności sortowania w kolumnie, nie aby określić sposób przechowywania danych.

Jeśli przechowujesz swoje dane jako Unicode, istnieje unikalny sposób ich reprezentacji, taki jest cel Unicode:nie ma potrzeby definiowania zestawu znaków, który jest kompatybilny ze wszystkimi językami, których będziesz używać :)

Pytanie brzmi:„co się dzieje, gdy przekazuję dane do serwera, który nie? Unicode?". Na przykład:

  • Kiedy wysyłam ciąg znaków UTF-8 do serwera, jak go rozumie?
  • Kiedy wysyłam ciąg znaków UTF-16 do serwera, jak go rozumie?
  • Kiedy wysyłam łańcuch Latin1 do serwera, jak go rozumie?

Z punktu widzenia serwera wszystkie te 3 ciągi to tylko strumień bajtów. Serwer nie może odgadnąć kodowania, w którym je zakodowałeś. Co oznacza, że ​​będziesz mieć kłopoty, jeśli twój klient odbc kończy wysyłanie bajtów (zakodowany ciąg) na serwer zamiast wysyłania unicode data:jeśli to zrobisz, serwer użyje predefiniowanego kodowania (takie było moje pytanie:jakiego kodowania użyje serwer? Skoro nie zgaduje, musi to być wartość parametru), a jeśli ciąg został zakodowany przy użyciu inne kodowanie, dzing , dane zostaną uszkodzone.

Jest dokładnie tak samo jak w Pythonie:

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')

Po prostu spróbuj. To zabawne. Odkodowany ciąg ma mieć postać „Hej, mam na imię André”, ale brzmi „Hej, mam na imię Andrテゥ”. é zostaje zastąpiony przez japoński テゥ

Stąd moja sugestia:musisz upewnić się, że pyodbc jest w stanie wysyłać dane bezpośrednio w formacie Unicode. Jeśli pyodbc tego nie zrobi, otrzymasz nieoczekiwane wyniki.

I opisałem problem w sposób Klient-Serwer. Ale ten sam rodzaj problemów może pojawić się podczas komunikacji zwrotnej z serwera do klienta. Jeśli Klient nie rozumie danych Unicode, prawdopodobnie wpadniesz w kłopoty.

FreeTDS obsługuje Unicode za Ciebie.

W rzeczywistości FreeTDS zajmuje się wszystkim za Ciebie i tłumaczy wszystkie dane na unicode UCS2. (Źródło ).

  • Serwer <--> FreeTDS:dane UCS2
  • FreeTDS <--> pyodbc :zakodowane ciągi, zakodowane w UTF-8 (z /etc/freetds/freetds.conf )

Więc spodziewałbym się, że twoja aplikacja będzie działać poprawnie, jeśli przekażesz dane UTF-8 do pyodbc. W rzeczywistości, ponieważ ten django-pyodbc bilet stany, django-pyodbc komunikuje się w UTF-8 z pyodbc, więc powinno być dobrze.

FreeTDS 0,82

Jednak cramm0 mówi, że FreeTDS 0.82 nie jest całkowicie wolny od błędów i że istnieją znaczne różnice między wersją 0.82 a oficjalną załataną wersją 0.82, którą można znaleźć tutaj . Powinieneś prawdopodobnie spróbować użyć poprawionego FreeTDS

Edytowane : usunięto stare dane, które nie miały nic wspólnego z FreeTDS, ale dotyczyły tylko komercyjnego sterownika odbc firmy Easysoft. Przepraszamy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Migawki bazy danych programu SQL Server -1

  2. Instalacja klastra pracy awaryjnej serwera SQL -4

  3. Jaki jest najlepszy sposób na tworzenie stronicowania w SQL Server?

  4. SQL Server LIKE zawierający znaki nawiasu kwadratowego

  5. nvarchar(max) nadal jest obcinany