Problema ao tentar gravar muitas casas decimais no BD

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
lucianotl
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Seg, 05 Abr 2010 3:48 pm
Localização: Florianopolis

Pessoal,

preciso gravar no banco de dados valores numéricos com 16 casas decimais, porém não estou conseguindo, o banco grava somente 14 as duas últimas ele bagunça e coloca um valor diferente do que eu gravei. Não funciona nem mesmo alimentando direto no plsql.

Já testei todos tipos de campo numéricos, number(34,16) por exemplo, mas sempre dá erro, alguém tem alguma dica?

atualmente estou gravando em um varchar2 multiplicando o valor por 10000000000000000 para remover a virgula.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Utilize o tipo de dados LONG,

create table x2 (a long)

insert into x2 values (10.1234567890123456)

dessa forma vai funcionar...
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Tava vendo achei um link interessante sobre data Types do Oracle,

inclusive acabei vendo que ele está depreciado, (descontinuado), é mantido apenas para compatibilidade, dessa forma, o ideal seria utilizar LOB,

CLOB, BLOB,

http://www.techonthenet.com/oracle/datatypes.php

abraço,
lucianotl
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Seg, 05 Abr 2010 3:48 pm
Localização: Florianopolis

Diego, vou testar o blob, só para complementar, tenho que fazer diversas operações matemáticas com o valor armazenado por isso estou tentando não usar o varchar2.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Certo, qualquer dúvida posta aí,

uma dica, existe o pacote DBMS_LOB, para manuseio de campos LOB,

posta o resultado aí...

abraço
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Por curiosidade, pra que tipo de aplicacao se usa um numero com 16 casas decimais ?
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Como você está tentando fazer isso? Posta o código por gentileza, e sua versão do Oracle.

No Oracle 10.2.0.4 funciona perfeitamente. Deve ser algum problema de conversão implícita no código que você está rodando, então só vendo. O Oracle aceita até 39 ou 40 dígitos significativos em data type number, e a escala decimal pode ir até 127 números após a vírgula (respeitando a precisão de até 40).

Só aconselho a usar number se possível, não tem motivo para armazenar em outro data type, até por questão de consistência de dados e evitar problemas futuros.

Selecionar tudo

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
Connected as fsitja
 
SQL> set serveroutput on
SQL> 
SQL> declare
  2    v_num number(30, 16) := 10.1234567890123456;
  3  begin
  4    dbms_output.put_line(v_num);
  5  end;
  6  /
 
10,1234567890123456
 
PL/SQL procedure successfully completed
 
SQL> 
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Francisco,

quando faz num insert realmente ele está tirando as 3 ultimas casas mesmo, deveria funcionar de acordo com alguns links que eu vi, estranho, deve ser alguma mascara, conversão, não sei não..

faz aí pra tu ver...

Me parece ser a máscara, quando roda assim chega mais perto do resultado

Selecionar tudo

create table xx (a 10,16);

insert into xx values (10.1234567890123456) 

select to_char(a, 'FM00D0000000000000000') FROM XX
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Blza Diego,

Realmente, trazendo no select simples, não exibe o restante dos números decimais, mas ele está armazenado lá, tanto que exibe quando é feita conversão explícita:

Selecionar tudo

SQL> create table xx (a number(30,16));
 
Table created
SQL> insert into xx values (10.1234567890123456);
 
1 row inserted
SQL> select a, to_char(a), to_char(a, 'TM') FROM XX;
 
                               A TO_CHAR(A)                               TO_CHAR(A,'TM')
-------------------------------- ---------------------------------------- ----------------------------------------------------------------
             10,1234567890123000 10,1234567890123456                      10,1234567890123456
 
SQL> 
Procurei na documentação se há alguma configuração NLS ou algo semelhante que limite o número mas não encontrei qual seria. Certamente há alguma, só não descobrimos onde ainda :wink:
targinosilveira
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Ter, 16 Set 2008 5:56 pm
Localização: Fortaleza - CE

Rapaz estive vendo o tipo numeric vai de 1 a 38 posições, você pega 16 posições após o ponto decimal, sobram 22 antes do ponto decimal que vai poder te dar um número absurdo. :D

Sem falar que você não precisará ficar fazendo cast para seus calculos lá na frente.

Deixo-me minha simples dica de que use o numeric mesmo.

Abraços..
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Bom, a documentação recomenda evitar o uso de Number, caso você precise usar a função para muitos cálculos aritméticos. Nesse caso o recomendado seria BINARY_FLOAT ou BINARY_DOUBLE (esse último para sua precisão numérica):

Selecionar tudo

SQL> create table xx (a BINARY_DOUBLE);
 
Table created
SQL> insert into xx values (10.1234567890123456);
 
1 row inserted
SQL> select a, to_char(a), to_char(a, 'TM') FROM XX;
 
         A TO_CHAR(A)                               TO_CHAR(A,'TM')
---------- ---------------------------------------- ----------------------------------------------------------------
10,1234567 1,0123456789012346E+001                  10,123456789012346
 
SQL> 
Repare que o select não mostra tudo de qualquer forma. É só representação de display, o que não quer dizer que os números não estejam sendo armazenados. Então pode ficar tranquilo que qualquer que seja a sua escolha está correto.
lucianotl
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Seg, 05 Abr 2010 3:48 pm
Localização: Florianopolis

o problema de usar lobs e afins é realmente ter que fazer o typecasting.
Se for assim continuarei com varchar2 mesmo, realmente eu gostaria de usar number e não ter que fazer conversões.

respondendo as dúvidas,

a versão é Oracle9i Enterprise Edition Release 9.2.0.8.0

A parte do sistema em questão é um gerador de cotas de selic, aplicando uma fórmula com um fator diário ele gera uma cota com dezesseis casas decimais. Quanto a função e conversão nas cotas com o fator diário tudo ocorre bem, o problema realmente ocorre quando vou gravar no bd.
um exemplo seria após aplicar a função eu tenho uma cota = 1,0006586484187329 em um dia.

Na hora de gravar no bd ele corta os dois últimos dígitos e coloca outros valores ali, quando faço select vem com os últimos dígitos alterados.
Eu preciso de todos os campos decimais porque a função do próximo dia usa essa cota do dia anterior.
lucianotl
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Seg, 05 Abr 2010 3:48 pm
Localização: Florianopolis

fsitja,

valeu a dica, começarei os testes com o BINARY_DOUBLE.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Segue abaixo o link com a referência dos Docs contendo a recomendação para Binary_Double:
http://download.oracle.com/docs/cd/E118 ... m#BABHCHCD

Luciano, já tive problemas parecidos de perder dados após a vírgula, em cálculos de quotas coincidentemente, porque numa das etapas do cálculo o valor era atribuído a uma variável no PL/SQL que tinha escala menor (no meu caso era um type de package definido com 10 casas e numa atribuição no meio do cálculo era jogado para uma variável de 8 casas. Essas duas eram "perdidas", até que me toquei que era erro na declaração da variável... :oops:
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 24 visitantes