it-swarm.dev

Caractere com codificação UTF8 não é equivalente no WIN1252

Eu estou recebendo a seguinte exceção:

Caused by: org.postgresql.util.PSQLException: ERROR: character 0xefbfbd of encoding "UTF8" has no equivalent in "WIN1252"

Existe uma maneira de erradicar esses caracteres, seja via SQL ou programaticamente? 
(A solução SQL deve ser preferida).

Eu estava pensando em se conectar ao banco de dados usando WIN1252, mas vai dar o mesmo problema.

28
Monis Iqbal

O que você faz quando recebe esta mensagem? Você importa um arquivo para o Postgres? Como devstuff disse, é um personagem BOM. Este é um caractere que o Windows grava como primeiro em um arquivo de texto, quando é salvo na codificação UTF8 - é um caracter invisível de 0 caracteres de largura, portanto você não o verá ao abri-lo em um editor de texto.

Tente abrir este arquivo, por exemplo, no Bloco de Notas, salve-o na codificação ANSI e adicione (ou substitua) a linha set client_encoding to 'WIN1252' no seu arquivo.

6
Tometzky

Eu tive um problema semelhante e resolvi, definindo a codificação para UTF8 com \encoding UTF8 no cliente antes de tentar uma INSERT INTO foo (SELECT * from bar WHERE x=y);. Meu cliente estava usando a codificação WIN1252, mas o banco de dados estava em UTF8, daí o erro.

Mais informações estão disponíveis no wiki do PostgreSQL em Suporte a conjunto de caracteres (devel docs).

24
Andy Terra

Não erradique os personagens, eles são reais e usados ​​por boas razões. Em vez disso, erradique Win1252.

5
MSalters

Parece que a seqüência de bytes 0xBD, 0xBF, 0xEF como um inteiro little-endian. Essa é a forma codificada em UTF8 do caractere 0xFEFF de marca de ordem de byte (BOM) Unicode.

Não tenho certeza do que é o comportamento normal do Postgre, mas a BOM normalmente é usada apenas para codificar a detecção no início de um fluxo de entrada e geralmente não é retornada como parte do resultado.

Em qualquer caso, sua exceção é devido a esse ponto de código não ter um mapeamento na página de código Win1252. Isso também ocorrerá com a maioria dos outros caracteres não latinos, como aqueles usados ​​em scripts asiáticos.

Você pode alterar a codificação do banco de dados para ser UTF8 em vez de 1252? Isso permitirá que suas colunas contenham quase qualquer caractere.

1
devstuff

Consegui contorná-lo usando a função substring do Postgres e selecionando:

select substring(comments from 1 for 200) from billing

O comentário de que o personagem especial iniciou cada campo foi uma grande ajuda para finalmente resolvê-lo.

1
Christian A Strasser

Eu tive um problema muito parecido. Eu tinha um servidor vinculado do SQL Server para um banco de dados PostgreSQL. Alguns dados que eu tinha na tabela que eu estava selecionando usando uma instrução openquery tinham algum caractere que não tinha um equivalente no Win1252. O problema é que a entrada DSN do Sistema (localizada no ODBC Administrador da Fonte de Dados) que eu usei para a conexão foi configurada para usar o PostgreSQL ANSI (x64) em vez do PostgreSQL Unicode (x64). Criar uma nova fonte de dados com o suporte a Unicode e criar um novo servidor vinculado modificado e referenciar o novo servidor vinculado em sua abertura resolveu o problema para mim. Dias felizes.

0
Maurice M

Este problema apareceu para nós em torno de 19/11/2016 com o nosso antigo Access 97 app acessando um postgresql 9.1 DB.

Isso foi resolvido alterando o driver para UNICODE em vez de ANSI (consulte o comentário do plang).

0
Maxime Langlois

Aqui está o que funcionou para mim: 1 habilitar consultas ad-hoc em sp_configure. 2 add ODBC DSN para o seu servidor PostgreSQL vinculado. 3 certifique-se ter ambos os drivers ANSI e Unicode (x64) (tente com ambos). 4 executar consulta como esta abaixo - mudar UID, ip do servidor, nome do banco de dados e senha. 5 apenas manter a consulta no último linha no formato postgreSQL.

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO

SELECT * FROM OPENROWSET('MSDASQL', 
'Driver=PostgreSQL Unicode(x64); 
uid=loginid;
Server=1.2.3.41;
port=5432;
database=dbname;
pwd=password',

'select * FROM table_name limit 10;')
0
s6a6n6d6m6a6n