2011-07-19 43 views
9

Por razones que no puedo evitar Tengo una columna varchar con datos como los siguientes: 820.0E-12, 10.0E + 00.Anotación de notación científica (de varchar -> numérico) en una vista

Quiero el valor numérico. Así que tengo este prueba consulta que funciona:

declare @d varchar(256) 
set @d = '820.0E-12' 
select 
    CASE 
     WHEN @d like '%E-%' THEN LTRIM(RTRIM(CAST(CAST(@d AS FLOAT) AS DECIMAL(18,18)))) 
     WHEN @d like '%E+%' THEN NULL 
     ELSE @d 
    END 

Mi resultado es: ,000000000820000000 (que es lo que quiero)

de que cambie de SQL para dar cuenta de los números> 0 (10.0E + 00) así:

WHEN @d like '%E+%' THEN CAST(@d AS FLOAT) 

mi resultado cambia a: 8.2e-10 (que no es lo que quiero)

Si cambio @ d = '10 .0E + 00' entonces consigo (lo cual es correcto).

Tengo la visión de que necesito hacer la salida de una columna varchar, que contiene notación científica, convertida en decimal (18,18).

¿Alguien puede decirme qué locura está pasando aquí?

O, tal vez mi pregunta debería ser, ¿cómo puedo convertir/convertir una columna de notación científica varchar a salida decimal en una vista?

Mi primera declaración CUANDO funciona para los números 0 < pero también deben tener en cuenta los números> 0. Cuando cambio el segundo cuando, para incluir el REPARTO, se rompe/da un resultado erróneo.

+0

Su código tal como fue anunciado está trabajando bien para mí ... de salida de la caja cuando cambio a un '12' E + es' 820000000000000' – JNK

Respuesta

12

Hay un par de problemas diferentes todos juntos aquí al mismo tiempo. Veamos algunos de ellos:

  1. Estás números de fundición como un decimal (18, 18). Lo que eso significa es "dame un número que tenga espacio para un TOTAL de 18 caracteres, y 18 de ellos deben ser después del decimal". Eso funciona bien siempre que su número sea menor que 0 (lo cual es cierto para todos los números E) pero se romperá si intenta usarlo en números> 0. Para números> 0, simplemente haga clic en DECIMAL sin especificar nada más .

  2. En el caso en el que se agrega "CUANDO @d como '% E +%' luego el yeso (@d como float)", que está obteniendo resultados diferentes para los números 0 < porque el motor está lanzando implícitamente el resultado de forma diferente . No conozco las reglas sobre cómo el servidor sql decide lanzar los resultados de CASE, pero al parecer hacer que el cambio propuesto haga que el motor lo reelabore de una manera diferente. Expulsar explícitamente esos resultados como un decimal resuelve el problema.

  3. Necesita LTRIM y RTRIM sus resultados consistentemente. Puede agregar LTRIM y RTRIM a cada declaración de caso, o puede simplemente LTRIM y RTRIM los resultados del caso.

he aquí una solución que se debe totalmente a resolver todo:

SELECT 
    LTRIM(RTRIM(CASE 
     WHEN @d like '%E-%' THEN CAST(CAST(@d AS FLOAT) AS DECIMAL(18,18)) 
     WHEN @d like '%E+%' THEN CAST(CAST(@d AS FLOAT) AS DECIMAL) 
     ELSE @d 
    END)) 
+0

me había pasado toda la mañana en esto. Después de publicar esta pregunta, me di cuenta de mi propio problema, como 5 minutos después. Gracias por tus explicaciones. –

3

puede utilizar ISO "real" tipo de datos


SELECT convert(numeric(18,18),convert(real,'820.0E-12')) 
--OR with more precision 
SELECT convert(numeric(18,18),convert(float(53),'820.0E-12')) 
0
mysql> select '820.0E-12' + 0, '10.0E+00' + 0; 
+-----------------+----------------+ 
| '820.0E-12' + 0 | '10.0E+00' + 0 | 
+-----------------+----------------+ 
| 0.00000000082 |    10 | 
+-----------------+----------------+ 

Es decir, la simple adición de 0 a varchar debería darle un valor numérico. (OK, puede que tenga un primer TRIM.)

esencialmente no hay caso de uso razonable para el m o n en FLOAT(m,n); simplemente declare las cosas FLOAT (para hasta aproximadamente 7 dígitos significativos) o DOUBLE (para aproximadamente 16).

Cuestiones relacionadas