sumas surealistas con funciones

01/06/2005 - 13:22 por Keyhelp | Informe spam
Hola a todos:
Hemos descubierto un "bug" en SQL Server 2000 con la suma de campos que
devuelve una función.

Supongamos que tenemos una tabla con una serie de importes separados en
columnas y tenemos una función que nos devuelve el importe según el campo y
la moneda
FN_IMPORTE ( MONEDA VARCHAR(3), CAMPO VARCHAR(8), SECUENCIA NUMERIC(3))

Luego tenemos una sentencia SELECT que ha de sumar los importes según una
determinada secuencia

SELECT SUM( FN_IMPORTE ( "EUR", "IMP1", TABLA.SECUENCIA)) TOT1,
SUM( FN_IMPORTE ( "EUR","IMP2", TABLA.SECUENCIA)) TOT2,
SUM(FN_IMPORTE ( "EUR","IMP3", TABLA.SECUENCIA)) TOT3
FROM TABLA;

El tema es que SIEMPRE devuelve el importe de la suma primera en TODAS las
columnas,
Es decir, si FN_IMPORTE("EUR","IMP1",TABLA.SECUENCIA) devuelve 1.000 tendré
un resultado de:
TOT1 --> 1.000
TOT2 --> 1.000
TOT3 --> 1.000

Si ahora modificamos la función para que el argumento variable sea el
primero, en vez de un argumento fijo, esta SELECT funciona correctamente.
SELECT SUM( FN_IMPORTE ( TABLA.SECUENCIA,"EUR", "IMP1")) TOT1,
SUM( FN_IMPORTE ( TABLA.SECUENCIA, "EUR","IMP2")) TOT2,
SUM(FN_IMPORTE ( TABLA.SECUENCIA,"EUR","IMP3")) TOT3
FROM TABLA;


TOT1 --> 1.000
TOT2 --> 2.400
TOT3 --> 1.850

Es bastante surealista pero esto está sucediendo con SQL Server 2000
Es mas. si no queremos cambiar la función, si hacemos lo siguiente
también sale bien, es decir, devuelve los importes que corresponden.
SELECT SUM( ( 1 * FN_IMPORTE ( TABLA.SECUENCIA,"EUR", "IMP1") / 1) TOT1,
SUM( ( 1 * FN_IMPORTE ( TABLA.SECUENCIA, "EUR","IMP2") / 1) TOT2,
SUM( ( 1* FN_IMPORTE ( TABLA.SECUENCIA,"EUR","IMP3") / 1 ) TOT3
FROM TABLA;

Pues nada, compañeros, esto es lo que hemos descubierto y si alguien sabe
algo al respecto, se admiten sujerencias.

Francisco López
Dpt. Desarrollo
Keyhelp, S.L.
http://www.keyhelp.net
 

Leer las respuestas

#1 Keyhelp
01/06/2005 - 13:29 | Informe spam
Perdon... se me olvidaba...
La última sentencia de ejemplo no es correcta, realmente hay que añadirle un
argumento que no varíe el resultado por cada uno de los sumatorios que
tengamos

SELECT SUM( 1 * FN_IMPORTE ( TABLA.SECUENCIA,"EUR", "IMP1")) TOT1,
SUM( ( 1 * 1 * FN_IMPORTE ( TABLA.SECUENCIA, "EUR","IMP2")) TOT2,
SUM( ( 1* 1 * 1 * FN_IMPORTE ( TABLA.SECUENCIA,"EUR","IMP3")) TOT3
FROM TABLA;

tampoco valdría poner solo 1 * FN_IMPORTE en cada uno de los sumatorios

Pues aqui queda reflejado el Surealismo "dalidiano" de SQL Server.

Francisco López
Dpt. Desarrollo
Keyhelp, S.L.
http://www.keyhelp.net
"Keyhelp" escribió en el mensaje
news:
Hola a todos:
Hemos descubierto un "bug" en SQL Server 2000 con la suma de campos que
devuelve una función.

Supongamos que tenemos una tabla con una serie de importes separados en
columnas y tenemos una función que nos devuelve el importe según el campo


y
la moneda
FN_IMPORTE ( MONEDA VARCHAR(3), CAMPO VARCHAR(8), SECUENCIA NUMERIC(3))

Luego tenemos una sentencia SELECT que ha de sumar los importes según una
determinada secuencia

SELECT SUM( FN_IMPORTE ( "EUR", "IMP1", TABLA.SECUENCIA)) TOT1,
SUM( FN_IMPORTE ( "EUR","IMP2", TABLA.SECUENCIA)) TOT2,
SUM(FN_IMPORTE ( "EUR","IMP3", TABLA.SECUENCIA)) TOT3
FROM TABLA;

El tema es que SIEMPRE devuelve el importe de la suma primera en TODAS las
columnas,
Es decir, si FN_IMPORTE("EUR","IMP1",TABLA.SECUENCIA) devuelve 1.000


tendré
un resultado de:
TOT1 --> 1.000
TOT2 --> 1.000
TOT3 --> 1.000

Si ahora modificamos la función para que el argumento variable sea el
primero, en vez de un argumento fijo, esta SELECT funciona correctamente.
SELECT SUM( FN_IMPORTE ( TABLA.SECUENCIA,"EUR", "IMP1")) TOT1,
SUM( FN_IMPORTE ( TABLA.SECUENCIA, "EUR","IMP2")) TOT2,
SUM(FN_IMPORTE ( TABLA.SECUENCIA,"EUR","IMP3")) TOT3
FROM TABLA;


TOT1 --> 1.000
TOT2 --> 2.400
TOT3 --> 1.850

Es bastante surealista pero esto está sucediendo con SQL Server 2000
Es mas. si no queremos cambiar la función, si hacemos lo siguiente
también sale bien, es decir, devuelve los importes que corresponden.
SELECT SUM( ( 1 * FN_IMPORTE ( TABLA.SECUENCIA,"EUR", "IMP1") / 1) TOT1,
SUM( ( 1 * FN_IMPORTE ( TABLA.SECUENCIA, "EUR","IMP2") / 1) TOT2,
SUM( ( 1* FN_IMPORTE ( TABLA.SECUENCIA,"EUR","IMP3") / 1 ) TOT3
FROM TABLA;

Pues nada, compañeros, esto es lo que hemos descubierto y si alguien sabe
algo al respecto, se admiten sujerencias.

Francisco López
Dpt. Desarrollo
Keyhelp, S.L.
http://www.keyhelp.net


Preguntas similares