Recentemente, tivemos um problema com a codificação relacionada a um campo que está sendo armazenado como um varchar (120) no SQL Server. No SSMS, o varchar aparece como:
"Quem matou JonBen?"
No entanto, quando é trazido para python, ele aparece como:
Eu pesquisei isso do lado do Python, e nada de estranho está acontecendo. Minha teoria é que o varchar no SQL Server está aceitando caracteres UTF-8 que são exibidos de maneira diferente em python e SSMS. Não estou muito familiarizado com a codificação no SQL Server. Alguém pode me informar o seguinte:
- Existe uma maneira no SSMS para exibir a codificação do varchar? Por exemplo, consulte \ x82 em vez de exibir a vírgula como atualmente é do SSMS?
- Estamos usando o SQL Server 2008. Existe alguma maneira de alterar a codificação de caracteres UTF-8 para caracteres ASCII sem usar ferramentas de importação / exportação ou despejar em um arquivo simples? Ou seja, posso fazer essa conversão através de uma consulta?
- Existe alguma maneira de identificar programaticamente registros problemáticos por meio de uma consulta (problema problemático sendo definido como caracteres UTF-8 que não são suportados pelo ASCII)?
Agradeço antecipadamente!
Usando sp_help N'table_name';
descobri que o Agrupamento desta VARCHAR
coluna é: SQL_Latin1_General_CP1_CI_AS
.
VARCHAR
coluna está usando?sp_help N'table_name';
. Olhe para a coluna com base em "nome" e, em seguida, olhe para a coluna "collation_name".Respostas:
O SQL Server não armazena UTF-8 em nenhuma circunstância. Você obtém UTF-16 Little Endian (LE) via
NVARCHAR
(incluindoNCHAR
eNTEXT
, mas nunca usaNTEXT
) eXML
, ou alguma codificação de 8 bits, com base em uma Página de Código, viaVARCHAR
(incluindoCHAR
eTEXT
, mas nunca usaTEXT
) .O problema aqui é que seu código está traduzindo incorretamente esse caractere 0x82, pensando que é UTF-8, mas não é. Não existe um "caractere" UTF-8 com um valor de 0x82, e é por isso que você obtém o símbolo "desconhecido" / substituição de " ". Consulte a seguinte tabela UTF-8, que mostra que não há caracteres para um byte único de 0x82:
Tabela de codificação UTF-8
Conforme declarado pelo OP, o agrupamento da coluna em questão é
SQL_Latin1_General_CP1_CI_AS
, o que significa que a codificação de 8 bits está usando o Code Page 1252, que é o Windows Latin 1 (ANSI) . E verificar se o valor do gráfico (role para baixo até o gráfico inferior, pois possui os nomes dos caracteres) 0x82 (procure "82" na coluna "Ponto do código") é, de fato, o único ponto baixo-9 entre aspas que você vê no SSMS. Esse personagem, em UTF-8, é uma seqüência de 3 bytes:E2 80 9A
.O que tudo isso significa é: seu código Python precisa definir a codificação do cliente para a conexão do SQL Server com a Code Page 1252 ou você precisa alterar / converter a codificação da string retornada do Code Page 1252 para UTF-8.
Obviamente, se isso estiver sendo exibido em uma página da web, você poderá alterar o conjunto de caracteres declarado da página
Windows-1252
, mas isso poderá interferir com outros caracteres da página, se já houver caracteres UTF-8.fonte