Olá,

Se você usa o to_number() para converter varchar2 em number provavelmente já teve esse problema ou um dia terá.
O problema aparenta ser simples quando tem uma variável varchar2 com caracteres estranhos no meio, mas e quando você tem certeza que o número esta certo. E quando to_number() funciona corretamente só quando o número é inteiro .
Essa dor de cabeça aparece quando tem o separador de decimal e/ou de milhar, que é diferente conforme a localização usada. Geralmente usamos o ponto, que é o normal para programadores. Mas o oracle pode te pegar de calças curtas.

Vamos usar a simples query abaixo para demonstrar o problema

select to_number('3.1415', '9D9999'), 1/2 from dual;

Rode a query abaixo para saber as configurações da sessão atual.

 select *
   from v$nls_parameters
  where parameter in
		('NLS_LANGUAGE', 'NLS_CHARACTERSET');

Se retornar isso:

   	PARAMETER	        VALUE
1	NLS_LANGUAGE	    BRAZILIAN PORTUGUESE
2	NLS_CHARACTERSET	WE8ISO8859P1

A query de exemplo vai retornar erro: ORA-01722: invalid number

SQL> select  to_number('3.1415', '9D9999'), 1/2 from dual;
select  to_number('3.1415', '9D9999'), 1/2 from dual
                  *
ERROR at line 1:
ORA-01722: invalid number

Se trocarmos o ponto pela vírgula vai funcionar perfeitamente

SQL>  select  to_number('3,1415', '9D9999'), 1/2 from dual;
TO_NUMBER('3,1415','9D9999')        1/2
---------------------------- ----------
                      3,1415         ,5

Para funcionar com ponto, o NLS_LANG deve ser o AMERICAN_AMERICA.WE8ISO8859P1, mostrado abaixo:

   	PARAMETER	        VALUE
1	NLS_LANGUAGE	    AMERICAN
2	NLS_CHARACTERSET	WE8ISO8859P1

Desse forma se usarmos o ponto vai funcionar.

SQL> select  to_number('3.1415', '9D9999'), 1/2 from dual
  2  ;
TO_NUMBER('3.1415','9D9999')        1/2
---------------------------- ----------
                      3.1415         .5

Com esse post demonstrei que o cliente é que manda, não sei tem como o DBA travar isso, mas pelo menos nos bancos que eu acesso tem essa característica.

Para alterar esse comportamento no linux basta usar o export para criar a variável NLS_LANG

export NLS_LANG="BRAZILIAN PORTUGUESE_BRAZIL.WE8ISO8859P1"
export NLS_LANG="AMERICAN_AMERICA.WE8ISO8859P1"

No windows vá nas propriedades do sistema, aba avançado e clique no botão variáveis de ambiente. Utilize o botão novo para criar uma nova variável, coloque no nome NLS_LANG e o valor que desejar.

Até mais,

Share

Olá

Escrevo este post para deixar uma dica para quem precisa integrar ADF com JasperReports. No blog GEBS foi publicado um artigo sobre esse tema com direito a exemplo para download.

Veja o artigo clicando no link a seguir: http://www.gebs.ro/blog/oracle/jasper-reports-in-adf/

Até mais

Roberto

Share

Olá

Hoje o Oracle me deu um baile, como faço todos os dias, estava eu tranquilo fazendo minha procedure PL/SQL quando de repente começo a obter esse erro:

LINE/COL ERROR
-------- ------------------------------------------
167/17   PL/SQL: ORA-00984: column not allowed here
160/7    PL/SQL: SQL Statement ignored

Olho aqui, olho lá, leio e releio as linha indicadas mas nada de ter uma luz para resolver esse problema. Resolvo criar o teste no PLSQL Developer (ver abaixo) com o trecho em torno da linha 167 mas o erro continua:

declare
  -- Local variables here
  i integer;
  --num_iden number;
  --num_cli number;
begin
  -- Test statements here
  insert into cad_endereco
    (num_cli_ende,
     cod_ende_ende,
     num_iden_ende,
     cod_ende_ende,
     cod_situ_ende,
     data_ende,
     usu_ende)
  values
    (num_cli,
     '0001',
     num_iden,
     '0001',
     'EN',
     '01',
     sysdate,
     user);
end;

Como o quantidade de código diminui e o scroolbar sumiu percebi que as variáveis num_cli e num_iden não estavam declaradas, lógico que não iria funcionar.
Visto isso, criei as benditas variáveis (no código acima estão comentadas). E não é que funcionou!!!

Poxa vida!! Não dava para me mostrar uma mensagem mais intuitiva do tipo a variável num_cli não está criada seu idiota??!! Mas com um column not allowed here é pra acabar com o meu dia. Já vi erro cuja mensagens não era assim uma beleza, mas essa ganhou disparado.

[desabafo mode=”off”]

Até mais,
Roberto

Share

Olá!

Caso você tem instalado um banco de dados Oracle 10g XE e não se lembra mais da senha do usuário SYS siga os passos abaixo para alterar a senha dele.

1) Abra o SQL*Plus. No botão iniciar escolha a opção “Executar Linha de Comandos SQL”;
2) Conecte-se com o comando abaixo:
SQL> connect / as sysdba
Conectado.

3) Altere a senha do usuário
SQL> alter user sys identified by ;
Usuário alterado.

Pronto. Agora você poderá acessar http://127.0.0.1:8080/apex/, digitar o usuário sys e a e ter o controle de volta do banco sem ter que reinstalá-lo.

Até mais,
Roberto

Share

IsNumber em Oracle PL/SQL

05/fevereiro/2010 - Oracle

Olá

Existem duas formas de verificar se uma string contém um número válido. A primeira forma é usando as funções translate, trim e length. Quando usadas em conjunto você obtém null se a string for número ou o comprimento da string sem espaços em branco. Veja abaixo:

select
length(trim(translate('minha_variavel', ' +-0123456789.', ' '))) n1,
length(trim(translate('123456789.9999', ' +-0123456789.',' '))) n2
from dual;

O resultado dessa query é:

N1    N2
14    null

Outra forma é usando a função to_number().  Caso a string passada contiver caracteres não numéricos é lançada uma exceção.

Observação: Um número na notação exponencial também será válido. Exemplo: 1E1

declare
n number;
s varchar2(10);
begin
s :=  '1236';
n :=  to_number(s);
dbms_output.put_line('É número');
exception when others then
dbms_output.put_line('Não é número');
end;
Share