Niedawno mieliśmy problem z kodowaniem związanym z polem, które jest przechowywane jako varchar (120) w SQL Server. W SSMS varchar pojawia się jako:
„Kto zabił JonBena?”
Jednak po wprowadzeniu do Pythona wygląda następująco:
Badałem to od strony Pythona i nic dziwnego się nie dzieje. Moja teoria jest taka, że varchar w SQL Server akceptuje znaki UTF-8, które wyświetlają się inaczej w pythonie niż SSMS. Nie znam się dobrze na kodowaniu w SQL Server. Czy ktoś może dać mi znać, co następuje:
- Czy jest jakiś sposób w SSMS, aby zobaczyć kodowanie varchara? Na przykład zobacz \ x82 zamiast wyświetlać przecinek, ponieważ obecnie pochodzi z SSMS?
- Używamy SQL Server 2008. Czy istnieje sposób na zmianę kodowania dowolnych znaków UTF-8 na znaki ASCII bez użycia narzędzi do importu / eksportu lub zrzutu do płaskiego pliku? Czy mogę dokonać tej konwersji za pomocą zapytania?
- Czy jest jakiś sposób na programową identyfikację problematycznych rekordów za pomocą zapytania (problematyczne jest definiowanie jako znaki UTF-8, które nie są obsługiwane przez ASCII)?
Z góry dziękuję!
Korzystanie sp_help N'table_name';
I okazało się, że układanie tej VARCHAR
kolumnie jest: SQL_Latin1_General_CP1_CI_AS
.
VARCHAR
używa ta kolumna?sp_help N'table_name';
. Spójrz na kolumnę opartą na „name”, a następnie spójrz na kolumnę „collation_name”.Odpowiedzi:
SQL Server nie przechowuje UTF-8 pod żadnym pozorem. Dostajesz UTF-16 Little Endian (LE) przez
NVARCHAR
(w tymNCHAR
iNTEXT
, ale nigdy nie używajNTEXT
) iXML
, lub jakieś 8-bitowe kodowanie, oparte na Stronie kodowej, przezVARCHAR
(w tymCHAR
iTEXT
, ale nigdy nie używajTEXT
) .Problem polega na tym, że Twój kod błędnie tłumaczy ten znak 0x82, sądząc, że jest to UTF-8, ale tak nie jest. Nie ma „znaku” UTF-8 o wartości 0x82, dlatego otrzymujesz symbol „nieznany” / zamienny „ ”. Zobacz poniższą tabelę UTF-8, która pokazuje, że nie ma znaku dla jednego bajtu 0x82:
Tabela kodowania UTF-8
Jak stwierdził OP, zestawienie kolumny
SQL_Latin1_General_CP1_CI_AS
, o której mowa, jest takie , co oznacza, że 8-bitowe kodowanie używa kodu Page 1252, którym jest Windows Latin 1 (ANSI) . A sprawdzenie tego wykresu (przewiń w dół do dolnego wykresu, ponieważ ma on nazwy znaków), wartość 0x82 (poszukaj „82” w kolumnie „Punkt kodowy”) jest w rzeczywistości pojedynczym nisko-9 cudzysłów , który widzisz w SSMS. Że postać, w UTF-8, to sekwencja 3 bajt:E2 80 9A
.Oznacza to wszystko: kod w języku Python musi albo ustawić kodowanie klienta dla połączenia SQL Server na stronę kodową 1252, albo trzeba zmienić / przekonwertować kodowanie zwracanego ciągu znaków z strony kodowej 1252 na UTF-8.
Oczywiście, jeśli to jest wyświetlana na stronie internetowej, to mogłoby zmienić deklarowaną charset strony, aby być
Windows-1252
, ale to może kolidować z innymi postaciami na stronie, jeśli istnieją znaki UTF-8 już istnieje.źródło