none
Converter nvarchar para numeric RRS feed

  • Pergunta

  • Bom dia...

    Utilizo um sistema que tem SQL Server 2005 como banco de dados. Ele possui uma tabela com um campo 'nvarchar(255)' que recebe todo tipo de informação, como números, nomes, etc. É um sistema proprietário, deconheço a razão do sistema ter sido desenvolvido desta forma, porém tenho acesso aos dados da tabela, pelo SQL Server.

    Tenho uma aplicação onde eu busco apenas os registros de valores numéricos desta tabela e os converto para 'numeric 18(2)'. Aconcete que quando os valores chegam a 7 caracteres esta conversão não é mais possível, é gerado um erro de conversão que não traz grandes detalhes, apenas diz que não é possível a operação.

    Realizando alguns testes descobri que utilizando o tipo 'float' não tenho problemas, porém não estão sendo gravadas as casas depois da vírgula, fica como se fosse um inteiro.

    Pergunto:
    - É uma boa utilizar o float no lugar do numeric, ou teria algum tipo que atende melhor?
    - Que prejuízos terei quanto a armazenamento e desempenho?
    - A questão das casas decimais pode ser resolvida?

    Grato...


    >>> Paz e Bem! Força Sempre! <<<
    quarta-feira, 9 de setembro de 2009 14:14

Respostas

  • Bom Dia,

    Acredito que o erro deva-se a um estouro das casas decimais já que o Numeric(18,2) suporta 16 casas inteiras e 2 decimais apenas. Um pequeno ajuste talvez resolva o seu problema.

    O tipo de dados FLOAT é flutuante e leva a valores aproximados e imprecisos. Você pode armazenar o valor 0.9999 e ele ser arredondado para 1.0 mesmo sem o seu consentimento.

    - É uma boa utilizar o float no lugar do numeric, ou teria algum tipo que atende melhor?
    Depende. Se você não tiver problemas com tipos aproximados, pode ser interessante, pois, ele pode economizar espaço. Lembre-se que utilizar tipos float na cláusula WHERE é perigoso, pois, como são aproximados, pode ser que não retorne nenhum resultado

    - Que prejuízos terei quanto a armazenamento e desempenho?
    O float é mais aproximado e tende a ocupar menos espaço. Não acredito que existam ganhos significativos de desempenho.

    - A questão das casas decimais pode ser resolvida?
    Pode. Acredito que isso ocorra por conta do texto no VARCHAR e não por uma limitação do tipo. Lembre-se que a SQL é inglesa e que uma vírgula por exemplo não significa casas decimais, mas sim casas de milhar

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Unique Constraints – Aplicações, Alternativas e um lapso "justificável" do SQL Server
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!710.entry
    Classifique as respostas. O seu feedback é imprescindível
    quarta-feira, 9 de setembro de 2009 14:54
  • Olá Vertão,

    O 18 significa 18 posições e o 2 significa 2 casas decimais. Então um DECIMAL(18,2) significa 18 posições com 2 posições decimais o que permite até 16 posições inteiras. Você teria um exemplo do erro e da sua conversão ? Fica mais fácil de trabalhar

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Unique Constraints – Aplicações, Alternativas e um lapso "justificável" do SQL Server
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!710.entry
    Classifique as respostas. O seu feedback é imprescindível
    • Marcado como Resposta Fernanda Simões terça-feira, 15 de setembro de 2009 18:16
    quarta-feira, 9 de setembro de 2009 16:41

Todas as Respostas

  • Bom Dia,

    Acredito que o erro deva-se a um estouro das casas decimais já que o Numeric(18,2) suporta 16 casas inteiras e 2 decimais apenas. Um pequeno ajuste talvez resolva o seu problema.

    O tipo de dados FLOAT é flutuante e leva a valores aproximados e imprecisos. Você pode armazenar o valor 0.9999 e ele ser arredondado para 1.0 mesmo sem o seu consentimento.

    - É uma boa utilizar o float no lugar do numeric, ou teria algum tipo que atende melhor?
    Depende. Se você não tiver problemas com tipos aproximados, pode ser interessante, pois, ele pode economizar espaço. Lembre-se que utilizar tipos float na cláusula WHERE é perigoso, pois, como são aproximados, pode ser que não retorne nenhum resultado

    - Que prejuízos terei quanto a armazenamento e desempenho?
    O float é mais aproximado e tende a ocupar menos espaço. Não acredito que existam ganhos significativos de desempenho.

    - A questão das casas decimais pode ser resolvida?
    Pode. Acredito que isso ocorra por conta do texto no VARCHAR e não por uma limitação do tipo. Lembre-se que a SQL é inglesa e que uma vírgula por exemplo não significa casas decimais, mas sim casas de milhar

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Unique Constraints – Aplicações, Alternativas e um lapso "justificável" do SQL Server
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!710.entry
    Classifique as respostas. O seu feedback é imprescindível
    quarta-feira, 9 de setembro de 2009 14:54
  • Olá Gustavo...

    Se o limite são 16 casas, acredito que não é este o problema, porque aconteceu quando atingiu 7 casas apenas, não sei. Então o que significa o '18' na declaração do 'numeric'? Pela documentação do SQL Server eu não entedi, a princípio achei que fosse a quantidade de casas inteiras, que eu acreditava chegar até '34'.

    Que tipo de ajuste você recomenda para que eu continue a utilizar o 'numeric'?

    Realmente, estou obtendo valores arredondados, geralmente eles vem como inteiros, sem as casas decimais. Seria interessante manter as casa decimais, por isso estava utilizando 'numeric'.

    Quanto à pontuação, tranquilo, os valores com que estou trabalhando estão com ponto, e não vírgula.


    >>> Paz e Bem! Força Sempre! <<<
    quarta-feira, 9 de setembro de 2009 16:25
  • Olá Vertão,

    O 18 significa 18 posições e o 2 significa 2 casas decimais. Então um DECIMAL(18,2) significa 18 posições com 2 posições decimais o que permite até 16 posições inteiras. Você teria um exemplo do erro e da sua conversão ? Fica mais fácil de trabalhar

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Unique Constraints – Aplicações, Alternativas e um lapso "justificável" do SQL Server
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!710.entry
    Classifique as respostas. O seu feedback é imprescindível
    • Marcado como Resposta Fernanda Simões terça-feira, 15 de setembro de 2009 18:16
    quarta-feira, 9 de setembro de 2009 16:41
  • Pois é, então é mais ou menos o que eu havia entendido mesmo, neste caso não era para acontecer o problema com um número do tipo 1234567.89, correto? Este é um exemplo de um número que gera erro ao ser gravado em um campo 'numeric(18,2)'.

    Estive dando uma olhada na procedure do sistema (não fui eu que desenvolvi, é proprietária), ela não chega a utilizar uma conversão no 'select', simplesmente ele cria uma tabela temporária com o campo 'numeric(18,2), importa os valores da tabela original com campo 'nvarchar(255)', faz alguns procedimentos da consulta, e depois grava na tabela definitiva, com campo do mesmo tipo.

    Consultando a tabela onde a informação ainda é 'nvarchar(255)' observei que a informação está sendo gravada com notação científica, e quando gravo essa informação em um campo 'float' ela fica assim:
    1.05539e+006 -> 1055390
    3.37596e+006 -> 3375960

    O mesmo não acontece com valores assim: 862099

    Que loucura isso, acho que vou acabar tendo que utilizar float mesmo.


    >>> Paz e Bem! Força Sempre! <<<
    quarta-feira, 9 de setembro de 2009 17:56