Foros del Web » Programando para Internet » PHP »

Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(campo)"

Estas en el tema de Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(campo)" en el foro de PHP en Foros del Web. Hola, gracias por leerme y por la ayuda... Hago una conexión desde PHP a SQL SERVER a través de ODBC. Ejecuto las consultas con odbc_exec(). ...
  #1 (permalink)  
Antiguo 25/11/2013, 05:51
 
Fecha de Ingreso: octubre-2007
Mensajes: 25
Antigüedad: 16 años, 6 meses
Puntos: 1
Pregunta Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(campo)"

Hola, gracias por leerme y por la ayuda...

Hago una conexión desde PHP a SQL SERVER a través de ODBC.
Ejecuto las consultas con odbc_exec().

Funcionan todas las querys (el código es correcto) excepto las que contienen en el select un sum(campo) cuando en alguna de las tuplas "campo" contiene un valor NULL.

$resultado=odbc_exec($conn,$row['consulta']);

$resultado está vacío si hay valores a NULL en un select sum(campo).

Si ejecuto la query directamente en el SQL Server funciona y devuelve datos.
El código es correcto pues funcionan OK todas las consultas excepto estos casos.

Cómo puedo conseguir que ignore los valores NULL o los convierta a cero??
No sé si es el driver ODBC, la versión de PHP... alguien sabe algo de ésto??

Espero haberme explicado correctamente!!
Mil gracias!!
  #2 (permalink)  
Antiguo 25/11/2013, 05:58
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(ca

Cita:
Funcionan todas las querys (el código es correcto) excepto las que contienen en el select un sum(campo) cuando en alguna de las tuplas "campo" contiene un valor NULL.
No creo que ese sea realmente el origen del problema.
El SQL, en todos los DBMS suma sólo valores no nulos, por lo que el uso de SUM sólo devuelve NULL si la suma es NULL, o mejor aún, si las condiciones del WHERE devuelven un resultado nulo (sin registros).
Muéstranos el código que ejecutas y un ejemplo de la ejecución manual.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 25/11/2013, 06:14
 
Fecha de Ingreso: octubre-2007
Mensajes: 25
Antigüedad: 16 años, 6 meses
Puntos: 1
Respuesta: Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(ca

Hola,

Gracias por la respuesta.

Te aseguro que ese el problema!!

El código funciona, porque depende de la consulta y si modifico la consulta haciendo que no coja valores NULL deja de fallar:

Por ejemplo:

select year(fecha) as "año", month(fecha) as "mes", sum(enviados) as emails from MITabla group by year(fecha), month(fecha) order by 1,2

Falla: $resultado está vacío, si hago un odbc_num_fileds por ejemplo me devuelve 0.

Sin embargo si modifico la query y añado la condición de que enviados sea mayor de 10, por ejemplo, ya funciona:

select year(fecha) as "año", month(fecha) as "mes", sum(enviados) as emails from tabla where enviados>10 group by year(fecha), month(fecha) order by 1,2

Es decir, si no sumo los valores a NULL si obtengo los datos.

También he comprobado que si hago un update de los NULL y los pongo a cero ya funciona la primera consulta. El problema es que en esa tabla muchas veces hay valores a NULL...

Lo que hago con los resultados es pintar gráficos y ya te digo que si la consulta no contiene el sum y no lee valores a NULL funciona correctamente.

Creo que es un problema del driver o algo así porque ha estado funcionando años y desde hace un tiempo han dejado de verse los gráficos. Antes funcionaba... te da alguna pìsta más??
  #4 (permalink)  
Antiguo 25/11/2013, 07:15
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(ca

Cuando alguien que trabaja mucho en SQL te diga que algo es de determinada forma, te sugiero que primero verifiques si lo que te dicen es cierto, consultando el manual de referencia.

Vamos al punto.
Según el manual de referencia On-Line de SQL Server:
Cita:
Devuelve la suma de todos los valores o solo de los valores DISTINCT de la expresión. SUM solo puede utilizarse con columnas numéricas. Los valores Null se pasan por alto.
¿Queda claro?
Los valores NULL que puedan existir en la columna no se suman, ni tampoco afectan el resultado.

Es decir: Si hay algún problema en la ejecución de la consulta desde PHP y por medio del ODBC, no es debido al SUM() o a los campos nulos que existan en los registros.

Lamentablemente, como no has posteado el código PHP que realiza la llamada, es imposible saber si el problema está en PHP, en el uso de ODBC, o bien está en alguna otra parte.
Cita:
Falla: $resultado está vacío, si hago un odbc_num_fileds por ejemplo me devuelve 0.
Por otro lado, si te está devolviendo cero columnas, lo más probable es que en realidad esté devolviendo un error de ejecución, o bien un error de datos, que tu no estás capturando.

Postea el PHP donde usas esta consulta, y si es posible la estructura real de la tabla, así como ejemplos de datos en ella y los usados al llamar a la consulta...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 26/11/2013, 04:28
 
Fecha de Ingreso: octubre-2007
Mensajes: 25
Antigüedad: 16 años, 6 meses
Puntos: 1
Respuesta: Hacer que un ODBC_EXEC() ignore valores NULL al ejecutar un "select sum(ca

Hola, gracias de nuevo, te pongo el código y los datos que necesitas, he comprobado que el problema sólo aparece cuando hay valores NULL en la columna que se lee para hacer el SUM(), no obstante, puede que se me escape algo...

El SQL funciona perfectamente, si ejecuto las consultas directamente sobre la BBDD efectivamente el sum() no coge los null, como debe ser y por supuesto, no afectan al resultado como comentas.
Código PHP:
       //Conecto a postgresql para sacar los datos del gráfico, incluida la consulta
        
$con=pg_connect("host=servidor dbname=intranet user=xxx password=xxxx");
    if (!
$con
         exit;

        
//Leemos la consulta para generar el gráfico  en una BBDD postgresql
         
gracias a un  parámetro recibido que indica el número de la consulta a leer
    
        $sacarquery
="select * from bbdd.graficos where codigo=".$_GET['qu'];
    
$resquery=pg_query($con,$sacarquery);
    
$row=pg_fetch_array($resquery);
    if(
trim($row['dsn'])!="" && trim($row['usuario'])!="" && trim($row['password'])!="")
    {
        
$conaux=odbc_connect(trim($row['dsn']),trim($row['usuario']),trim($row['password']));
        if (!
$conaux
            echo 
"ERROR AL CONECTAR A LA BASE DE DATOS POR ODBC";
        
//La conexión es correcta, se usa siempre el mismo dsn, usuario y password, para todas las consultas
        
        
$resultado=odbc_exec($conaux,trim($row['consulta']));
        
         echo 
"NUM ROWS:".odbc_num_rows($resultado)."<br><br>\n"
                
// devuelve -1 tanto si falla como si funciona, he leido que dependiendo de la versión    puede ocurrir eso
         
         
echo "RESULTADO:".$resultado."<br><br>\n"
                
//devuelve Resource id #14 tanto si falla como si funciona
         
         
echo "NUM CAMPOS:".odbc_num_fields($resultado)."\n<br><br>";
                
//Devuelve 0 cuando la consulta falla, si no, devuelve el número de campos         
//Por ejemplo, para:
//select year(fecha) as "año", month(fecha) as "mes", sum(enviados) as emails from MITabla group by year(fecha), month(fecha) order by 1,2 -> DEVUELVE CERO
//Para:
select year(fecha) as "año"month(fecha) as "mes"sum(enviados) as emails from MITabla [B]where enviados>0[/Bgroup by year(fecha), month(fechaorder by 1,-> DEVUELVE 3
 
//Cuando he probado estas dos consultas lo hago directamente leyéndolas de base de datos, hago el update para añadir la condición, el proceso es exactamente igual, sólo cambia la query y sólo falla cuando el SUM coge valores NULL, eso es seguro porque he hecho varias pruebas, como quitar los NULL y ponerlos a cero y funciona, ok??

         
echo "MSG ERROR:".odbc_errormsg($conaux)."\n";
                
//No devuelve mensaje ni cuando falla
            
}
           if (
$resultado) --> entra siempreaunque la query falle
           
{
                                        
$tupla=Array(); 
                                        
$err=odbc_fetch_into($resultado,$tupla);
//Esta línea ya da error: odbc_fetch_into(): No tuples available at this result index y ya no sigue
                    
$i=0;
                    while(
$err==true)
                    {
                        
//Se leen datos para pintar el gráfico
                    
}           
           } 
La prueba que tengo por la que te digo que no funciona por los campos NULL es porque éstos gráficos han estado funcionado durante años y ahora ya no funcionan, no se han cambiado ni consultas, ni base de datos, ni estructura de la tabla, ni conexión, ni código, lo único que entiendo que haya podido pasar es una actualización del driver ODBC o del PHP.

No te pongo estrucutura de tabla porque son muchas queys a muchas tablas y en todos los casos que aparece un SUM() y que hay valores a NULL en ese campo a sumar no obtengo datos. Da siempre el mismo error:
odbc_fetch_into(): No tuples available at this result index

Si ejecuto las consultas directamente en el SQL Server funcionan OK.

Te pongo un link de un Bug de PHP que, creo, que está relacionado con este problema...
https://bugs.php.net/bug.php?id=61387

Si te fijas, le da el mismo problema que a mi al ejecutar un SUM().

Gracias de nuevo!!

Etiquetas: null, select, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:56.