Páginas

sexta-feira, 9 de março de 2012

ORA-01843: not a valid month

Estou aqui de novo para comentar problemas relacionados ao desenvolvimento com Oracle, e como eles foram resolvidos.

Na equipe que trabalho entrou uma pessoa nova, e precisamos instalar o cliente do Oracle para que ele pudesse trabalhar. Após feita a instalação do Oracle Instant Client, quando ele começou a executar o sistema na sua máquina, o seguinte erro apareceu: ORA-01843: not a valid month. Detalhe que quando a mesma rotina era executada na minha máquina, eu não tinha esse problema.

Após algumas pesquisas, identificamos a causa. No banco de dados que estamos utilizando, a configuração de formato de data está parametrizado para dia/mês/ano:


select * from nls_database_parameters;

NLS_LANGUAGE                          AMERICAN
NLS_TERRITORY                          AMERICA
NLS_CURRENCY                          $
NLS_ISO_CURRENCY                  AMERICA
NLS_NUMERIC_CHARACTERS  .,
NLS_CHARACTERSET                  WE8ISO8859P1
NLS_CALENDAR                         GREGORIAN
NLS_DATE_FORMAT                 DD-MON-RR
NLS_DATE_LANGUAGE                  AMERICAN
NLS_SORT                                         BINARY
NLS_TIME_FORMAT                         HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT         DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT                 HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY                $
NLS_COMP                                        BINARY
NLS_LENGTH_SEMANTICS        BYTE
NLS_NCHAR_CONV_EXCP        FALSE
NLS_NCHAR_CHARACTERSET    AL16UTF16
NLS_RDBMS_VERSION               11.2.0.2.0


No entanto, na máquina do desenvolvedor não havia configuração de como o cliente do Oracle trataria as informações. Desse modo, ele estava considerando o retorno de formato de data como no padrão mês/dia/ano. Quando a rotina era executada, ela retornava uma data, digamos 16/02/11. No formado brasileiro, teríamos o 16 como dia, mas lendo isso no formado padrão, 16 seria o mês, o que não existe. Por isso ocorria o erro de not a valid month.

A correção foi incluir uma parametrização no registro do Windows informando que era para ser considerado o formato brasileiro. Ou seja, incluir a propriedade NLS_LANG com valor BRAZILIAN PORTUGUESE_BRAZIL.WE8MSWIN1252 dentro da chave HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient11g_home1 (este caminho pode variar, dependendo de como foi feita a instalação do cliente).


Mas muito importante, tivemos que reiniciar a máquina para essa parametrização surtir efeito. Depois disso, tudo funcionou ok.

Obs. Eu não sei se essa é a forma correta de corrigir o problema, mas foi o que funcionou. Se alguém conhecer um jeito mais elegante, por favor, comente aqui.

ATUALIZAÇÃO: 23/05/2013

Com uma máquina nova, novamente tive que recorrer à Internet para resolver este problema. Infelizmente, não foi possível utilizar esta mesma solução, pois na estação que estou usando o Oracle não está instalado com o instalador, mas simplesmente copiando os binários e ajustando o caminho nas variáveis de ambiente do Windows (Path). Por isso, não estava disponível a chave no registry que comentei acima.

A solução? Criar uma nova variável de ambiente, chamada NLS_LANG, onde coloquei novamente o valor BRAZILIAN PORTUGUESE_BRAZIL.WE8MSWIN1252. Reiniciei e tudo funcionou.

[]'s

4 comentários:

  1. No meu caso aqui, nem precisei reiniciar o meu servidor Windows 2003 R2. Estava setado para "AMERICAN_AMERICA.WE8MSWIN1252". Foi só trocar para o indicado do post e funcionou!

    Obrigado ao Google por me indicar este blog!

    ResponderExcluir
  2. Meus Parabéns!!!
    Me salvou...!
    Obrigado por compartilhar.

    ResponderExcluir
  3. Resolvi com este comando:
    ALTER SESSION SET NLS_DATE_FORMAT = 'MM-DD-YYYY';

    Extraído do artigo: https://www.codeproject.com/Tips/997250/How-to-Resolve-the-Not-a-Valid-Month-Error-with-Or

    ResponderExcluir