Ontem comentei o meu problema com charset entre Oracle e uma aplicação web que estou fazendo. O problema era o seguinte: ao preencher campos de texto de um formulário com caracteres acentuados, os mesmos eram inseridos como se fossem dois caracteres de interrogação (??).
Essa aplicação tem como pré-requisito o uso de UTF-8, pois é feita com o framework Ruby on Rails. Minhas buscas pelo Google tinham me colocado apenas em uma direção: modificar o charset do banco de dados a partir de um penoso procedimento de backup/restore. Mas, conversando com o meu colega de trabalho Luiz (que não tem blog, infelizmente) descobri que ele já havia tido o mesmo problema antes e a solução, aparentemente, era bem mais simples (e mágica).
O Rails interage com o Oracle por intermédio da biblioteca Ruby oci8. A solução mágica consiste em definir a variável de ambiente NLS_LANG com o valor BRAZILIAN PORTUGUESE_BRAZIL.UTF8 antes que o código da biblioteca seja carregado. Mais informações oficiais sobre a variável aqui e aqui.
De acordo com a documentação oficial, essa variável não especifica apenas 1, mas 3 valores: LINGUAGEM_TERRITÓRIO.CHARSET. No meu caso, portanto, foram especificados:
- LINGUAGEM:
BRAZILIAN PORTUGUESE - TERRITÓRIO:
BRAZIL - CHARSET:
UTF8
Note que, para a minha aplicação web, apenas o CHARSET é relevante. Até onde li na documentação, LINGUAGEM e TERRITÓRIO servem mais para indicar ao Oracle como ele deve exibir mensagens de erro ou formatar datas para apresentação. CHARSET parece indicar ao Oracle que faça uma conversão entre o charset real do banco de dados e o valor do charset especificado em NLS_LANG no momento da leitura de dados. Portanto, os dados continuam sendo armazenados com o charset original, mas quando o Rails solicita esses dados a partir da biblioteca oci8, o Oracle os converte para UTF-8 (neste caso) e depois os entrega. Essa parece ser uma boa explicação para o correto funcionamento da aplicação após a definição dessa variável, mas o problema que relato ao fim do artigo mostra que, na prática, a teoria é outra.
Testei duas maneiras de definir essa variável. A primeira é colocar a seguinte linha no arquivo ~/.bashrc do usuário no qual o servidor de aplicação roda:
export NLS_LANG='BRAZILIAN PORTUGUESE_BRAZIL.UTF8'
Mas acho mais interessante embutir essa declaração dentro do próprio código da aplicação. Não sei qual o local mais apropriado para isso, mas inserir esta linha no início do arquivo config/environment.rb funcionou:
ENV['NLS_LANG']='BRAZILIAN PORTUGUESE_BRAZIL.UTF8'
Essa solução resolveu o problema completamente? Não. Para textos inseridos a partir da aplicação web, caracteres acentuados são gravados no banco de dados e lidos da forma correta (não são substituídos por um ou dois sinais de interrogação). Mas essa solução estava simples demais para ser verdade, certo?
Como estou desenvolvendo a aplicação web sobre um banco de dados já existente, e que já possui dados, rodei o servidor de aplicação em modo de produção para ver se os dados já existentes eram apresentados corretamente também. Resultado: problemas de acentuação novamente. Os caracteres acentuados lidos do banco de dados são trocados por pontos de interrogação.
RSS Feed
Twitter
Posted in
Tags: 
Acredito que você está com alguma configuração errada na sua base Oracle para ter este problema na hora de visualizar os resultados.
Aqui eu tenho uma base Oracle com o charset WE8ISO8859P1 (basta rodar um “select * from nls_database_parameters where parameter=’NLS_CHARACTERSET’” para descobrir o charset da sua base). Configurei a variavel de ambiente conforme você sugeriu e já tive tudo funcionando corretamente.
Uma outra possibilidade pode ser que vc precise configurar a constante do ruby-oci8 chamada DEFAULT_OCI8_ENCODING com um valor de encoding default (por ex.: DEFAULT_OCI8_ENCODING=’ISO-8859-1′) – referencia: http://ruby-oci8.rubyforge.org/en/News2_0.html#l5
Espero que alguma dessas dicas seja util. A sua dica funcionou perfeitamente para mim. Obrigado…
Até mais,
Augusto Souza