Escritura 0.001
a Postgres (9.1 a 9.3) a través de un adaptador de datos .net resulta en un extraño 0.00
valor (en pgAdmin) que aparece como cero pero no lo es.
De hecho, consultas simples como SELECT 1/(SELECT "weird_field" ...) FROM ...
da correctamente 1000
.
Las consultas más complicadas (con división) resultan sorprendentemente en una division by zero
error.
Además, ordenar por en Navicat muestra correctamente esos valores entre 0.0011 y 0.0009
Usamos bibliotecas Devart para conectarnos a la base de datos, pero el culpable parece ser el adaptador de datos (o al menos la combinación de estos dos) porque una simple consulta directa, aún a través de controladores Devart, no produce el mismo resultado.
¿Alguna idea de lo que está pasando?
--
EDITAR:
El tipo en la base de datos es numeric
, en el programa se representa como double
decimal
.
pSQL imprime esto:
--
0.00
(1 fila)
--
EDIT 2:
log_statement = "all"
da un resultado MÁS extraño:
UPDATE "TABLE" SET ... "WEIRD_FIELD"=$8 ... WHERE ...
DETAIL: parameters: $1 = "7", $2 = "7", $3 = "18", $4 = "18", $5 = "V03", $6 = "Hz",
$7 = "Hz", $8 = "0.00", $9 = "0", $10 = "2", $11 = "0"
El parámetro para el campo extraño se imprime como cero (0.00), pero claramente no es ...
Tenga en cuenta que el valor en DataGridView poblado por DataAdapter muestra la correcta 0.001
.
--
EDITAR 3 (Maurice):
El problema con el adaptador Devart parece serreparado. Usando la última versión, ya no veo el problema. Creo que está relacionado con esta solución específica: 7.3.293 20-Nov-14: Se corrigió el error con la pérdida de precisión al trabajar con PgSqlType.Numeric a través del protocolo 3 Actualicé mi software usando los últimos ensamblajes de Devart y ahora todo funciona como se esperaba.
Respuestas
2 para la respuesta № 1Descubrimos que el problema está en la forma en que PgSql representa numeric
s (decimal) con precisión y escala no especificadas.
El valor en la base de datos parece ser correcto (0.001
) pero en algunas operaciones está truncado:
"weird_field" + 0.001
---------------------
0.002
pero
"weird_field" * 2
--------------------
0.00
y
"weird_field" * 5
--------------------
0.01
Esto también explica por qué algunas consultas dan un division by zero
error.
La solución es especificar precisión y escala., por ejemplo elegimos numeric(38,28)
(que también usamos para decimal en Oracle) y todo funciona bien.
--
En cuanto a la documentación de PgSql, no encontramos nada sobre este comportamiento, por lo que creemos que es un error:
Especificando:
NUMÉRICO
sin ninguna precisión o escala crea una columnaen el que se pueden almacenar valores numéricos de cualquier precisión y escala, hasta el límite de implementación de precisión. Una columna de este tipo no impondrá valores de entrada a ninguna escala en particular, mientras que las columnas numéricas con una escala declarada impondrán valores de entrada a esa escala.
Lo extraño es también que 0.000001
(et similia) no se trunca, mientras que 0.001
hace.