Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Resultado null de una select en un procedimiento almacenado

Estas en el tema de Resultado null de una select en un procedimiento almacenado en el foro de Mysql en Foros del Web. Buenos días. Tengo un problema con una select que tengo creada en un procedimiento almacenado. DECLARE PRUEBA INT; SELECT ANYTRA FROM VENTAS_CLIENTE_REPRE_BACKUP INTO PRUEBA; RETURN ...
  #1 (permalink)  
Antiguo 01/03/2011, 03:40
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Resultado null de una select en un procedimiento almacenado

Buenos días.

Tengo un problema con una select que tengo creada en un procedimiento almacenado.

DECLARE PRUEBA INT;
SELECT ANYTRA FROM VENTAS_CLIENTE_REPRE_BACKUP INTO PRUEBA;
RETURN PRUEBA;

Esta select me retorna como valor NULL. La tabla contiene un registro con valores diferentes de NULL.

Pero si utilizo
SELECT COUNT(*) FROM VENTAS_CLIENTE_REPRE_BACKUP
El resultado que me devuelve es correcto, 1.


Si alguien me puede echar una mano, gracias.
  #2 (permalink)  
Antiguo 01/03/2011, 04:12
Avatar de Heimish2000  
Fecha de Ingreso: enero-2011
Ubicación: Madrid
Mensajes: 844
Antigüedad: 13 años, 2 meses
Puntos: 89
Respuesta: Resultado null de una select en un procedimiento almacenado

Puede que la tabla tenga un registro cuyo campo ANYTRA sea null, de esa manera la primera consulta devolveria null (porque coges el valor del campo) y la segunda devuelve uno (porque cuentas el número de registros de la tabla)
  #3 (permalink)  
Antiguo 01/03/2011, 04:51
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Como comento arriba, la tabla sólo tiene un registro y este campo tiene el valor 2011.
  #4 (permalink)  
Antiguo 01/03/2011, 04:58
Avatar de Heimish2000  
Fecha de Ingreso: enero-2011
Ubicación: Madrid
Mensajes: 844
Antigüedad: 13 años, 2 meses
Puntos: 89
Respuesta: Resultado null de una select en un procedimiento almacenado

No veo donde lo comentas arriba, la verdad...

¿Que te devuelve si haces SELECT * FROM tabla? ¿Puedes postear aquí el resultado?
  #5 (permalink)  
Antiguo 01/03/2011, 05:30
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Si hago lo que me comentas funciona correctamente.

Lo que no entiendo como con SELECT * funciona y con SELECT ANYTRA no.

Esto quiere decir que no podría hacer DISTINCTS si me hiciera falta ya que tengo que sacar todas la columnas.
  #6 (permalink)  
Antiguo 01/03/2011, 05:50
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Porque no se pueden hacer operaciones con NULL. NULL no es un valor sino un puntero a la nada, a la inexistencia o a un estado indeterminado (según el caso).
¿Puedes contar las indeterminaciones o la nada? No, y tampoco puedes a una variable real pasarle una indeterminación. Lo único que puedes hacer es definir qué hacer si es NULL o establecer que es un NULL.

Lee un poco acerca del tratamiento de los NULL en MySQL: 3.3.4.6. Trabajar con valores NULL
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 01/03/2011, 05:54
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Por otro lado, estás diciendo que el asunto está en un procedimiento almacenado, pero RETURN no es una sentencia de procedimientos almacenados sino de funciones almacenadas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 01/03/2011, 06:03
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Perdón, he puesto mal el titulo. Sería una función si.

Pero mi duda está en que la columna no vale NULL. Tiene como valor 2011, pero sólo me lo coge bien con el Select *.
  #9 (permalink)  
Antiguo 01/03/2011, 06:38
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Magnífico, pero ¿cómo haces para recuperar el valor de esa función? ¿En qué contexto y con qué consulta la usas?
¿Puedes postear todo el código SQL completo?, es decir tanto el código completo del SF, como la consulta donde la usas
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 01/03/2011, 06:49
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Aqui al función.

DELIMITER $$

DROP FUNCTION IF EXISTS `CUR` $$
CREATE DEFINER=`root`@`%` FUNCTION `CUR`() RETURNS int(4)
BEGIN
DECLARE PRUEBA INT(4) DEFAULT 999;

DECLARE done INT DEFAULT 0;
DECLARE ANYTRA INT(4);
DECLARE W_ANYTRA INT(4);
DECLARE MESTRA int(2);
DECLARE NOMMES varchar(15);
DECLARE NCUENTA varchar(30);
DECLARE NOMCLIENTE varchar(255);
DECLARE CODREPRE varchar(20);
DECLARE NOMREPRE varchar(50);
DECLARE MES_ACTUAL_IMP float(15,2);
DECLARE MES_ACTUAL_CANT float(15,2);
DECLARE IMPBRU float(11,2);
DECLARE DTOFAM float(11,2);
DECLARE DTOART float(11,2);
DECLARE DTOCAB float(11,2);
DECLARE DTOOTR float(11,2);
DECLARE PRECIO float(11,2);
DECLARE PRECOS float(11,2);
DECLARE VAR_MES_ANT_IMP float(15,2);
DECLARE VAR_MES_ANT_IMP_PCT float(10,2);
DECLARE VAR_MES_ANT_CANT float(15,2);
DECLARE VAR_MES_ANT_CANT_PCT float(10,2);
DECLARE VAR_FIN_ANY_IMP float(15,2);
DECLARE VAR_FIN_ANY_IMP_PCT float(10,2);
DECLARE VAR_FIN_ANY_CANT float(15,2);
DECLARE VAR_FIN_ANY_CANT_PCT float(10,2);
DECLARE VAR_INTERANUAL_IMP float(15,2);
DECLARE VAR_INTERANUAL_IMP_PCT float(10,2);
DECLARE VAR_INTERANUAL_CANT float(15,2);
DECLARE VAR_INTERANUAL_CANT_PCT float(10,2);
DECLARE VAR_PRESUPUESTO_IMP float(15,2);
DECLARE VAR_PRESUPUESTO_IMP_PCT float(10,2);
DECLARE VAR_PRESUPUESTO_CANT float(15,2);
DECLARE VAR_PRESUPUESTO_CANT_PCT float(10,2);




DECLARE CUR_VENTAS_CLIENTE_REPRE CURSOR FOR
SELECT *
FROM VENTAS_CLIENTE_REPRE_BACKUP;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;


OPEN CUR_VENTAS_CLIENTE_REPRE;

REPEAT
FETCH CUR_VENTAS_CLIENTE_REPRE INTO ANYTRA,MESTRA,NOMMES,NCUENTA,NOMCLIENTE,CODREPRE,N OMREPRE,MES_ACTUAL_IMP,MES_ACTUAL_CANT,IMPBRU,DTOF AM,DTOART,DTOCAB,DTOOTR,PRECIO,PRECOS,VAR_MES_ANT_ IMP,vAR_MES_ANT_IMP_PCT,VAR_MES_ANT_CANT,VAR_MES_A NT_CANT_PCT,VAR_FIN_ANY_IMP,VAR_FIN_ANY_IMP_PCT,VA R_FIN_ANY_CANT,VAR_FIN_ANY_CANT_PCT,VAR_INTERANUAL _IMP,VAR_INTERANUAL_IMP_PCT,VAR_INTERANUAL_CANT,VA R_INTERANUAL_CANT_PCT,VAR_PRESUPUESTO_IMP,VAR_PRES UPUESTO_IMP_PCT,VAR_PRESUPUESTO_CANT,VAR_PRESUPUES TO_CANT_PCT;

IF NOT done THEN
/* Inserción de los registros de referencia agrupados por CLIENTE y REPRE */
INSERT INTO VENTAS_CLIENTE_REPRE_BACKUP VALUES (ANYTRA,MESTRA,NULL,NCUENTA,NOMCLIENTE,CODREPRE,NO MREPRE,MES_ACTUAL_IMP,MES_ACTUAL_CANT,IMPBRU,DTOFA M,DTOART,DTOCAB,DTOOTR,PRECIO,PRECOS,VAR_MES_ANT_I MP,vAR_MES_ANT_IMP_PCT,VAR_MES_ANT_CANT,VAR_MES_AN T_CANT_PCT,VAR_FIN_ANY_IMP,VAR_FIN_ANY_IMP_PCT,VAR _FIN_ANY_CANT,VAR_FIN_ANY_CANT_PCT,VAR_INTERANUAL_ IMP,VAR_INTERANUAL_IMP_PCT,VAR_INTERANUAL_CANT,VAR _INTERANUAL_CANT_PCT,VAR_PRESUPUESTO_IMP,VAR_PRESU PUESTO_IMP_PCT,VAR_PRESUPUESTO_CANT,VAR_PRESUPUEST O_CANT_PCT);
UPDATE VENTAS_CLIENTE_REPRE_BACKUP SET NOMMES=InformarNombreMes(MESTRA);
END IF;
UNTIL done END REPEAT;

CLOSE CUR_VENTAS_CLIENTE_REPRE;

RETURN ANYTRA;

END $$

DELIMITER ;


Y la llamada.

select cur();

El resultado me lo devuelve como si fuera una columna de una tabla.


El problema que veo con esta solución a parte de no poder hacer DISTINCT es el siguiente, utilizando el SELECT *, si la tabla sobre la que lo hago me cambia (+ o -columnas), entonces tendría que cambiar todas las Funciones donde estubiera esta tabla, para añadirle las variables de destino en le INTO.

De ahi viene mi pregunta de saber porque razón con el SELECT * funciona pero con el SELECT ANYTRA no funciona.
  #11 (permalink)  
Antiguo 01/03/2011, 07:08
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Bueno, ahora me queda amás claro (aunque no termino de entender todo este procedimiento para algo que puedes obtener con dos o tres consultas directamente).
Paso a explicar: ANYTRA toma el valor del campo correspondiente en la tabla origen en cada FETCH, pero el último FETCH, el que pone done en 1, trata de acceder a un registro que no existe y es precisamente eso lo que controla el HANDLER. Como el puntero trata de ir más allá de los registros de la tabla, y estos no existen, el valor devuelto por ese último FETCH es NULL...
Este es un tema que a veces no se conoce si no lo has leido en profundidad, no te preocupes. El punto esencial es que como FETCH devuelve NULL en ese momento, todos los campos del INTO se vuelve NULL... simplemente.
De hecho, si en lugar de RETURN ANYTRA se pudiese hacer un SELECT a todos los campos, comprobarías que todos los valores están en NULL.
El error consiste en pretender obtener el último valor real que tuvo ANYTRA en esta forma. No lo puedes hacer así. Yo en tu caso usaría otra variable INT, la cual sólo llenaría con el valor de ANYTRA dentro del IF y la usaría para el RETURN.
De todos modos, a mi entender, esto se puede hacer sin un CURSOR, y con menos complicaciones.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #12 (permalink)  
Antiguo 01/03/2011, 09:43
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Gracias por adelantado, pero creo que quizas no me he acabado de explicar del todo.

Mi idea original es agrupar todos los registros de la tabla original por Año y Mes y sumarizar unas cantidades que tengo en la tabla.
Y luego hacer unos Updates con cantidades de años anteriores.

El cursor que he enviado es una primera prueba de lo que queria hacer.
Como no me funcionaba pues he ido simplificando la query.
Lo que supongo que al enviar toda la copia lo he liado más.

Creo que todavía no he sido capaz de explicar el problema que tengo.
Centrandonos en el caso del cursor, si la definición del mismo es como "Select *" devuelve bien los datos, pero si es como "Select ANYTRA" el resultado que me devuelve es NULL.
Si ejecuto el cursor lo que me hace es insertarme los n registros de la tabla origen en la tabla destino pero con el valor a NULL.



Vuelvo a enviar el procedimiento con el problema original, pero solo con la Select.

DELIMITER $$

DROP FUNCTION IF EXISTS `CUR` $$
CREATE DEFINER=`root`@`%` FUNCTION `CUR`() RETURNS int(4)
BEGIN
DECLARE PRUEBA INT(4) DEFAULT 999;

DECLARE done INT DEFAULT 0;
DECLARE ANYTRA INT(4);
DECLARE W_ANYTRA INT(4);
DECLARE MESTRA int(2);
DECLARE NOMMES varchar(15);
DECLARE NCUENTA varchar(30);
DECLARE NOMCLIENTE varchar(255);
DECLARE CODREPRE varchar(20);
DECLARE NOMREPRE varchar(50);
DECLARE MES_ACTUAL_IMP float(15,2);
DECLARE MES_ACTUAL_CANT float(15,2);
DECLARE IMPBRU float(11,2);
DECLARE DTOFAM float(11,2);
DECLARE DTOART float(11,2);
DECLARE DTOCAB float(11,2);
DECLARE DTOOTR float(11,2);
DECLARE PRECIO float(11,2);
DECLARE PRECOS float(11,2);
DECLARE VAR_MES_ANT_IMP float(15,2);
DECLARE VAR_MES_ANT_IMP_PCT float(10,2);
DECLARE VAR_MES_ANT_CANT float(15,2);
DECLARE VAR_MES_ANT_CANT_PCT float(10,2);
DECLARE VAR_FIN_ANY_IMP float(15,2);
DECLARE VAR_FIN_ANY_IMP_PCT float(10,2);
DECLARE VAR_FIN_ANY_CANT float(15,2);
DECLARE VAR_FIN_ANY_CANT_PCT float(10,2);
DECLARE VAR_INTERANUAL_IMP float(15,2);
DECLARE VAR_INTERANUAL_IMP_PCT float(10,2);
DECLARE VAR_INTERANUAL_CANT float(15,2);
DECLARE VAR_INTERANUAL_CANT_PCT float(10,2);
DECLARE VAR_PRESUPUESTO_IMP float(15,2);
DECLARE VAR_PRESUPUESTO_IMP_PCT float(10,2);
DECLARE VAR_PRESUPUESTO_CANT float(15,2);
DECLARE VAR_PRESUPUESTO_CANT_PCT float(10,2);



SELECT * INTO ANYTRA,MESTRA,NOMMES,NCUENTA,NOMCLIENTE,CODREPRE,N OMREPRE,MES_ACTUAL_IMP,MES_ACTUAL_CANT,IMPBRU,DTOF AM,DTOART,DTOCAB,DTOOTR,PRECIO,PRECOS,VAR_MES_ANT_ IMP,vAR_MES_ANT_IMP_PCT,VAR_MES_ANT_CANT,VAR_MES_A NT_CANT_PCT,VAR_FIN_ANY_IMP,VAR_FIN_ANY_IMP_PCT,VA R_FIN_ANY_CANT,VAR_FIN_ANY_CANT_PCT,VAR_INTERANUAL _IMP,VAR_INTERANUAL_IMP_PCT,VAR_INTERANUAL_CANT,VA R_INTERANUAL_CANT_PCT,VAR_PRESUPUESTO_IMP,VAR_PRES UPUESTO_IMP_PCT,VAR_PRESUPUESTO_CANT,VAR_PRESUPUES TO_CANT_PCT from VENTAS_CLIENTE_REPRE_backup;



RETURN ANYTRA;

END $$

DELIMITER ;


En este caso me funciona bien porque he puesto "Select *", si esta select la cambio y pongo los nombres de las columnas entonces es cuando me devuelve NULL.
  #13 (permalink)  
Antiguo 01/03/2011, 10:17
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Me parece que no estás entendiendo la idea:
El CURSOR lo usas para leer uno a uno un conjunto de registros dado, luego, con cada registro si y sólo si no has superado el límite (SQLSTATE '02000'), haces un INSERT. Pero si has llegado al final, el último FETCH devuelve NULL y pone done = 1, por lo que no entra en el IF que contiene el INSERT, pero sí realiza la asignación de NULL a todas las variables.
¿Se entiende ahora?
A partir de ese último FETCH, ANYTRA contiene un NULL.
Para que te devuelva el valor de ANYTRA la idea sería:

Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3.   DECLARE PRUEBA INT(4) DEFAULT 999;
  4.   DECLARE done INT DEFAULT 0;
  5.   /* ------------------------------------------------------------------------ */
  6.   DECLARE T_ANYTRA INT(4);
  7.   /* ------------------------------------------------------------------------ */
  8.   DECLARE ANYTRA INT(4);
  9.   DECLARE W_ANYTRA INT(4);
  10.   DECLARE MESTRA int(2);
  11.   DECLARE NOMMES varchar(15);
  12.   DECLARE NCUENTA varchar(30);
  13.   DECLARE NOMCLIENTE varchar(255);
  14.   DECLARE CODREPRE varchar(20);
  15.   DECLARE NOMREPRE varchar(50);
  16.   DECLARE MES_ACTUAL_IMP float(15,2);
  17.   DECLARE MES_ACTUAL_CANT float(15,2);
  18.   DECLARE IMPBRU float(11,2);
  19.   DECLARE DTOFAM float(11,2);
  20.   DECLARE DTOART float(11,2);
  21.   DECLARE DTOCAB float(11,2);
  22.   DECLARE DTOOTR float(11,2);
  23.   DECLARE PRECIO float(11,2);
  24.   DECLARE PRECOS float(11,2);
  25.   DECLARE VAR_MES_ANT_IMP float(15,2);
  26.   DECLARE VAR_MES_ANT_IMP_PCT float(10,2);
  27.   DECLARE VAR_MES_ANT_CANT float(15,2);
  28.   DECLARE VAR_MES_ANT_CANT_PCT float(10,2);
  29.   DECLARE VAR_FIN_ANY_IMP float(15,2);
  30.   DECLARE VAR_FIN_ANY_IMP_PCT float(10,2);
  31.   DECLARE VAR_FIN_ANY_CANT float(15,2);
  32.   DECLARE VAR_FIN_ANY_CANT_PCT float(10,2);
  33.   DECLARE VAR_INTERANUAL_IMP float(15,2);
  34.   DECLARE VAR_INTERANUAL_IMP_PCT float(10,2);
  35.   DECLARE VAR_INTERANUAL_CANT float(15,2);
  36.   DECLARE VAR_INTERANUAL_CANT_PCT float(10,2);
  37.   DECLARE VAR_PRESUPUESTO_IMP float(15,2);
  38.   DECLARE VAR_PRESUPUESTO_IMP_PCT float(10,2);
  39.   DECLARE VAR_PRESUPUESTO_CANT float(15,2);
  40.   DECLARE VAR_PRESUPUESTO_CANT_PCT float(10,2);
  41.  
  42.   DECLARE CUR_VENTAS_CLIENTE_REPRE CURSOR FOR
  43.   SELECT * FROM VENTAS_CLIENTE_REPRE_BACKUP;
  44.  
  45.   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
  46.  
  47.   OPEN CUR_VENTAS_CLIENTE_REPRE;
  48.  
  49.     FETCH CUR_VENTAS_CLIENTE_REPRE INTO
  50.       ANYTRA,MESTRA,NOMMES,NCUENTA,NOMCLIENTE,CODREPRE,N OMREPRE,
  51.       MES_ACTUAL_IMP,MES_ACTUAL_CANT,IMPBRU,DTOF AM,DTOART,DTOCAB,
  52.       DTOOTR,PRECIO,PRECOS,VAR_MES_ANT_ IMP,vAR_MES_ANT_IMP_PCT,VAR_MES_ANT_CANT,
  53.       VAR_MES_A NT_CANT_PCT,VAR_FIN_ANY_IMP,VAR_FIN_ANY_IMP_PCT,
  54.       VAR_FIN_ANY_CANT,VAR_FIN_ANY_CANT_PCT,VAR_INTERANUAL _IMP,
  55.       VAR_INTERANUAL_IMP_PCT,VAR_INTERANUAL_CANT,VA R_INTERANUAL_CANT_PCT,
  56.       VAR_PRESUPUESTO_IMP,VAR_PRES UPUESTO_IMP_PCT,VAR_PRESUPUESTO_CANT,
  57.       VAR_PRESUPUESTO_CANT_PCT;
  58.     IF NOT done THEN
  59.       /* Inserción de los registros de referencia agrupados por CLIENTE y REPRE */
  60.       INSERT INTO VENTAS_CLIENTE_REPRE_BACKUP
  61.       VALUES(ANYTRA, MESTRA, NULL, NCUENTA, NOMCLIENTE, CODREPRE, NOMREPRE,
  62.       MES_ACTUAL_IMP, MES_ACTUAL_CANT, IMPBRU, DTOFAM,
  63.       DTOART,DTOCAB,DTOOTR,PRECIO,PRECOS,
  64.       VAR_MES_ANT_I MP,vAR_MES_ANT_IMP_PCT,VAR_MES_ANT_CANT,
  65.       VAR_MES_AN T_CANT_PCT,VAR_FIN_ANY_IMP,VAR_FIN_ANY_IMP_PCT,
  66.       VAR _FIN_ANY_CANT,VAR_FIN_ANY_CANT_PCT,VAR_INTERANUAL_IMP,
  67.       VAR_INTERANUAL_IMP_PCT,VAR_INTERANUAL_CANT,VAR_INTERANUAL_CANT_PCT,
  68.       VAR_PRESUPUESTO_IMP,VAR_PRESU PUESTO_IMP_PCT,
  69.       VAR_PRESUPUESTO_CANT,VAR_PRESUPUEST O_CANT_PCT);
  70.  
  71.       UPDATE VENTAS_CLIENTE_REPRE_BACKUP SET NOMMES=InformarNombreMes(MESTRA);
  72.       /* ------------------------------------------------------------------------ */
  73.       SET T_ANYTRA = ANYTRA;
  74.       /* ------------------------------------------------------------------------ */
  75.     END IF;
  76.   UNTIL done END REPEAT;
  77.  
  78.   CLOSE CUR_VENTAS_CLIENTE_REPRE;
  79.  
  80.   RETURN T_ANYTRA;
  81. END $$
  82.  
  83. DELIMITER ;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 01/03/2011, 11:17
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Creo que sigo sin saber explicar el origen del problema. Quiza he juntado demasiados temas.

Digamos que quiero hacer dos cosas en la función.
Primera: devolver como parámetro el valor de ANYTRA.
Segunda: insertar los registros de la tabla origen a la tabla destino.

Primera:
Lo del cursor lo entiendo, en la ultima pasada del FETCH está todo a NULL, con lo que al intentar devolverlo como parámetro de la función me da NULL. Correcto.

Segunda:
El caso es que si monto el cursor con "Select *" inserta los registros correctamente.
Si el cursor lo monto con "Select ANYTRA", a la hora de insertar los registros lo que hace es insertarlos todos a NULL.
Tanto si es el primero como si es el último (contando como último el que tiene datos, ya que si no, no pasa por el INSERT)


Y aparte del tema del cursor.
La prueba simple que he hecho, es una "SELECT ANYTRA" a pelo, sin cursores ni nada, esta SELECT me devuelve NULL, no esta dentro de un cursor ni nada, o sea, no es un FETCH, es una SELECT pura y dura.
Si la hago la "SELECT *", me funciona correctamente.

Mi duda reside ahí en que me devuelve NULL la columna de la tabla, no en si es el primero o último registro. Ya que al ser una SELECT sólo me devuelve un registro (porque mi tabla solo tiene un registro)
  #15 (permalink)  
Antiguo 01/03/2011, 12:57
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Cita:
Segunda:
El caso es que si monto el cursor con "Select *" inserta los registros correctamente.
Si el cursor lo monto con "Select ANYTRA", a la hora de insertar los registros lo que hace es insertarlos todos a NULL.
Tanto si es el primero como si es el último (contando como último el que tiene datos, ya que si no, no pasa por el INSERT)
Pregunta del millón: ¿ANYTRA es el nombre de la columna que almacena ese valor y además es el nombre de la variable?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #16 (permalink)  
Antiguo 02/03/2011, 03:18
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Si, es el mismo.

He probado a cambiar el nombre de la Variable para que no coincidiera pero ocurre lo mismo. Y tambien he probado con las variables que empiezan con la @, pero igual.
  #17 (permalink)  
Antiguo 03/03/2011, 08:00
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Hola gnzsoloyo.

Me podrías confirmar algo de este tema, si te suena que puede estar sucediendo o no se te ocurre nada.


Gracias de antemano.
  #18 (permalink)  
Antiguo 03/03/2011, 08:32
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Francamente me gustaría hacer pruebas directas para terminar de analizar por qué te da ese resultado. Sería bueno contar con una copia de la base para probar, pero bueno...
Respecto a los nombres, MySQL trabaja en forma jerárquica con los objetos de base de datos, por eso no es buena práctica usar los mismos nombres entre objetos distintos, como es el caso de mismo nombre para tablas, bases, columnas o variables. Eso puede hacer confundir al parser.
Uno de los resultados que he visto en ocasiones es que si pones el mismo nombre a una variable que a una tabla, la sentencia SET variable = variable devuelve NULL, porque no se puede asignar una tabla a una variable en MySQL. Esto pasa porque el objeto de mayor jerarquía pisa al de menor, y el parser interpreta que te refieres a la tabla...
Además de eso, si usas variables de usuario (las que llevan "@" como prefijo), deben ser inicializadas antes de ser usadas, porque su valor inicial es siempre NULL. Por eso un
Código MySQL:
Ver original
  1. SELECT A FROM tabla INTO @B
devuelve un NULL.
Para usarla lo primero es incializarla con un valor que le defina el tipo (que tampoco tienen), y además que sea un valor sin significado:
Código MySQL:
Ver original
  1. SET @v_anytra = 0;
  2. SET @v_anytra = T_ANYTRA;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #19 (permalink)  
Antiguo 03/03/2011, 10:53
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Gracias.

Aun a malas te puedo enviar un backup en txt de la base de datos, pero claro, por aqui no se puede.


La verdad que es un caso muy raro, que de una forma funcione y de la otra no, y claro con el * no me sirve porque necesito hacer GROUP BY y Sumatorios de columnas.
  #20 (permalink)  
Antiguo 03/03/2011, 11:06
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Fíjate de comprimirlo y subirlo a algún servicio de archivos en web. NO recuerdo en este momento el link de ninguno, pero debe ser simple ubicarlos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #21 (permalink)  
Antiguo 04/03/2011, 02:59
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Aqui te envío el link

http://www.filedropper.com/testbackup201103040953

La función es la CUR()



Carlos
  #22 (permalink)  
Antiguo 04/03/2011, 03:35
 
Fecha de Ingreso: abril-2008
Mensajes: 93
Antigüedad: 16 años
Puntos: 10
Respuesta: Resultado null de una select en un procedimiento almacenado

Hola Carlos

Lo primero que te aconsejo es que borres ese fichero si los datos son de producción, ya que has mandado un backup completo.

Continuando con el post, y revisando el backup enviado, tu problema está aquí:

Código:
INSERT INTO `ventas_cliente_repre_backup` (`ANYTRA`,`MESTRA`,`NOMMES`,`NCUENTA`,`NOMCLIENTE`,`CODREPRE`,`NOMREPRE`,`MES_ACTUAL_IMP`,`MES_ACTUAL_CANT`,`IMPBRU`,`DTOFAM`,`DTOART`,`DTOCAB`,`DTOOTR`,`PRECIO`,`PRECOS`,`VAR_MES_ANT_IMP`,`VAR_MES_ANT_IMP_PCT`,`VAR_MES_ANT_CANT`,`VAR_MES_ANT_CANT_PCT`,`VAR_FIN_ANY_IMP`,`VAR_FIN_ANY_IMP_PCT`,`VAR_FIN_ANY_CANT`,`VAR_FIN_ANY_CANT_PCT`,`VAR_INTERANUAL_IMP`,`VAR_INTERANUAL_IMP_PCT`,`VAR_INTERANUAL_CANT`,`VAR_INTERANUAL_CANT_PCT`,`VAR_PRESUPUESTO_IMP`,`VAR_PRESUPUESTO_IMP_PCT`,`VAR_PRESUPUESTO_CANT`,`VAR_PRESUPUESTO_CANT_PCT`) VALUES 
 (NULL,NULL,'NO INFORMADO',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (NULL,NULL,'NO INFORMADO',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (NULL,NULL,'NO INFORMADO',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
Como puedes ver, la columna ANYTRA no tiene valor en ninguna de las 4 filas.
  #23 (permalink)  
Antiguo 04/03/2011, 03:47
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

No son datos de producción. Por eso lo he enviado.

Esta sería la tabla de destino, con lo que el resultado que haya ahí no es el problema.

No es problema de datos. El problema está en la función.

Gracias de todos modos.

Carlos
  #24 (permalink)  
Antiguo 04/03/2011, 06:48
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Gracias por darme acceso al backup. Si lo quieres retirar ya, no hay problema.
Estuve probando y revisando todo luego de cargar la base de prueba y hay algunos detalles que resolver:
- La tabla "VENTAS_CLIENTE_REPRE_BACKUP" carece de PK, por lo que puede llegar a registrarse más de un backup conteniendo los mismos datos. Eso puede ser eventualmente un error, que favorece que se llene de "basura". La misma tabla tampoco evita que sus valores sea null, lo que también ayuda a guardar datos "basura".
- El backup muestra que se han almacenado datos "basura", lo que te dará problemas al momento de realizar pruebas.
- Un error que debes estar recibiendo es que la consulta devmuelve más de una fila. Eso sucede en esta parte:
Código MySQL:
Ver original
  1. SELECT ANYTRA, MESTRA, NOMMES FROM VENTAS_CLIENTE_REPRE_BACKUP
  2. INTO ANYTRA, MESTRA, NOMMES;
Como la tabla contiene más de un registro, no puedes volcarlo a variables sin antes restringir la cantidad de registros devueltos a uno solo.
- Lo que comprobé es que los valores no se insertan en la tabla en cuestión cuando se usan los nombres de las columnas como nombres de variables. Deben ser diferentes.

Lo que quisiera que me expliques es el sentido de este último segmento, luego de cerrar el cursor. ¿Por qué pones esos NULL?:
Código MySQL:
Ver original
  1. SELECT MAX(ANYTRA), MAX(MESTRA), NOMMES FROM VENTAS_CLIENTE_REPRE_BACKUP LIMIT 1
  2.   INTO VANYTRA, VMESTRA, VNOMMES;
  3.  
  4.   INSERT INTO VENTAS_CLIENTE_REPRE_BACKUP VALUES
  5. (VANYTRA, 1, 'ENERO', 45, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 04/03/2011 a las 07:02
  #25 (permalink)  
Antiguo 04/03/2011, 07:27
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Bien, finalmente encontré los problemas que generaban el error:
1) La variable "done" estaba creada, pero no inicializada, por lo que su valor real era NULL y en ese caso todo el proceso del IF falla. No se puede hacer un IF contra un NULL, sino contra una función para NULLs.
2) Resuelto eso, la cantidad de valores a ingresar en esa tabla no se corresponde con la cantidad de columnas de la tabla. En ese caso lo que corresponde hacer es o bien poner ,todos los valores necesarios, o indicar los valores que se usarán.
Quedó finalmente así:

Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. DROP PROCEDURE IF EXISTS `test`.`CUR` $$
  4. CREATE DEFINER=`root`@`%` PROCEDURE `CUR`()
  5.   DECLARE done INT DEFAULT 0;
  6.   DECLARE VANYTRA int(4);
  7.   DECLARE VMESTRA int(2);
  8.   DECLARE VNOMMES varchar(15);
  9.   DECLARE VNCUENTA varchar(30);
  10.   DECLARE VNOMCLIENTE varchar(255);
  11.   DECLARE VCODREPRE varchar(20);
  12.   DECLARE VNOMREPRE varchar(50);
  13.   DECLARE VMES_ACTUAL_IMP float(15,2);
  14.   DECLARE VMES_ACTUAL_CANT float(15,2);
  15.   DECLARE VIMPBRU float(11,2);
  16.   DECLARE VDTOFAM float(11,2);
  17.   DECLARE VDTOART float(11,2);
  18.   DECLARE VDTOCAB float(11,2);
  19.   DECLARE VDTOOTR float(11,2);
  20.   DECLARE VPRECIO float(11,2);
  21.   DECLARE VPRECOS float(11,2);
  22.   DECLARE VAR_MES_ANT_IMP float(15,2);
  23.   DECLARE VAR_MES_ANT_IMP_PCT float(10,2);
  24.   DECLARE VAR_MES_ANT_CANT float(15,2);
  25.   DECLARE VAR_MES_ANT_CANT_PCT float(10,2);
  26.   DECLARE VAR_FIN_ANY_IMP float(15,2);
  27.   DECLARE VAR_FIN_ANY_IMP_PCT float(10,2);
  28.   DECLARE VAR_FIN_ANY_CANT float(15,2);
  29.   DECLARE VAR_FIN_ANY_CANT_PCT float(10,2);
  30.   DECLARE VAR_INTERANUAL_IMP float(15,2);
  31.   DECLARE VAR_INTERANUAL_IMP_PCT float(10,2);
  32.   DECLARE VAR_INTERANUAL_CANT float(15,2);
  33.   DECLARE VAR_INTERANUAL_CANT_PCT float(10,2);
  34.   DECLARE VAR_PRESUPUESTO_IMP float(15,2);
  35.   DECLARE VAR_PRESUPUESTO_IMP_PCT float(10,2);
  36.   DECLARE VAR_PRESUPUESTO_CANT float(15,2);
  37.   DECLARE VAR_PRESUPUESTO_CANT_PCT float(10,2);
  38.   /* ------------------------------------------------------------------------------- */
  39.   DECLARE CUR_VENTAS_CLIENTE_REPRE CURSOR FOR
  40.           SELECT ANYTRA,MESTRA,InformarNombreMes(MESTRA) AS NOMMES,NCUENTA,NOMCLIENTE,REPRE AS CODREPRE,NOMREPRE,SUM(IMPNET) AS MES_ACTUAL_IMP,COUNT(*) AS MES_ACTUAL_CANT,
  41.                  SUM(IMPBRU) AS IMPBRU,SUM(DTOFAM) AS DTOFAM,SUM(DTOART) AS DTOART,SUM(DTOCAB) AS DTOCAB,SUM(DTOOTR) AS DTOOTR,SUM(PRECIO)/COUNT(*) AS PRECIO,SUM(PRECOS) AS PRECOS
  42.           FROM DADESVENDES
  43.           WHERE NCUENTA IS NOT NULL
  44.           GROUP BY ANYTRA,MESTRA,NCUENTA,NOMCLIENTE,CODREPRE,NOMREPRE;
  45.   /* ------------------------------------------------------------------------------- */
  46.   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
  47.   /* ------------------------------------------------------------------------------- */
  48.   OPEN CUR_VENTAS_CLIENTE_REPRE;
  49.   /* ------------------------------------------------------------------------------- */
  50.     FETCH CUR_VENTAS_CLIENTE_REPRE INTO
  51.             VANYTRA,
  52.             VMESTRA,
  53.             VNOMMES,
  54.             VNCUENTA,
  55.             VNOMCLIENTE,
  56.             VCODREPRE,
  57.             VNOMREPRE,
  58.             VMES_ACTUAL_IMP,
  59.             VMES_ACTUAL_CANT,
  60.             VIMPBRU,
  61.             VDTOFAM,
  62.             VDTOART,
  63.             VDTOCAB,
  64.             VDTOOTR,
  65.             VPRECIO,
  66.             VPRECOS;
  67.     IF NOT done THEN
  68.       /* ------------------------------------------------------------------------------- */
  69.       /* Inserción de los registros de referencia agrupados por CLIENTE y REPRE */
  70.       /* ------------------------------------------------------------------------------- */
  71.       INSERT INTO VENTAS_CLIENTE_REPRE_BACKUP(
  72.         ANYTRA,
  73.         MESTRA,
  74.         NOMMES,
  75.         NCUENTA,
  76.         NOMCLIENTE,
  77.         CODREPRE,
  78.         NOMREPRE,
  79.         MES_ACTUAL_IMP,
  80.         MES_ACTUAL_CANT,
  81.         IMPBRU,
  82.         DTOFAM,
  83.         DTOART,
  84.         DTOCAB,
  85.         DTOOTR,
  86.         PRECIO,
  87.         PRECOS)
  88.     VALUES
  89.         (VANYTRA,
  90.         VMESTRA,
  91.         VNOMMES,
  92.         VNCUENTA,
  93.         VNOMCLIENTE,
  94.         VCODREPRE,
  95.         VNOMREPRE,
  96.         VMES_ACTUAL_IMP,
  97.         VMES_ACTUAL_CANT,
  98.         VIMPBRU,
  99.         VDTOFAM,
  100.         VDTOART,
  101.         VDTOCAB,
  102.         VDTOOTR,
  103.         VPRECIO,
  104.         VPRECOS);
  105.     END IF;
  106.   UNTIL done END REPEAT;
  107.   /* ------------------------------------------------------------------------------- */
  108.   CLOSE CUR_VENTAS_CLIENTE_REPRE;
  109.   /* ------------------------------------------------------------------------------- */
  110.   SELECT MAX(ANYTRA), MAX(MESTRA), NOMMES FROM VENTAS_CLIENTE_REPRE_BACKUP LIMIT 1
  111.   INTO VANYTRA, VMESTRA, VNOMMES;
  112.   /* ------------------------------------------------------------------------------- */
  113.   SELECT VANYTRA, VMESTRA, VNOMMES;
  114. END $$
  115.  
  116. DELIMITER ;
La última parte es una adaptación de lo que pusiste para que devuelva algo.

Queda pendiente resolver lo de las PK de las tablas, ya que no se está controlando la unicidad de valores.
Tampoco hay un buen uso de la programación de SP y SF en algunos casos, en los que se están haciendo operaciones innecesariamente complicadas, como por ejemplo en la función `InformarNombreMes`, que yo escribiría así:
Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. DROP FUNCTION IF EXISTS `InformarNombreMes` $$
  4. CREATE FUNCTION `InformarNombreMes`(COD INT) RETURNS varchar(15) CHARSET latin1
  5.   CASE COD
  6.     WHEN 1 THEN
  7.       RETURN 'ENE';
  8.     WHEN 2 THEN
  9.       RETURN 'FEB';
  10.     WHEN 3 THEN
  11.       RETURN 'MAR';
  12.     WHEN 4 THEN
  13.       RETURN 'ABR';
  14.     WHEN 5 THEN
  15.       RETURN 'MAY';
  16.     WHEN 6 THEN
  17.       RETURN 'JUN';
  18.     WHEN 7 THEN
  19.       RETURN 'JUL';
  20.     WHEN 8 THEN
  21.       RETURN 'AGO';
  22.     WHEN 9 THEN
  23.       RETURN 'SEP';
  24.     WHEN 10 THEN
  25.       RETURN 'OCT';
  26.     WHEN 11 THEN
  27.       RETURN 'NOV';
  28.     WHEN 12 THEN
  29.       RETURN 'DIC';
  30.     ELSE
  31.       RETURN 'NO INFORMADO';
  32.   END CASE;
  33. END $$
  34.  
  35. DELIMITER ;
Es un poco más limpio y al parser le resulta más eficiente.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 04/03/2011 a las 07:35
  #26 (permalink)  
Antiguo 08/03/2011, 03:07
 
Fecha de Ingreso: marzo-2011
Mensajes: 23
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: Resultado null de una select en un procedimiento almacenado

Buenos dias.

Muchas gracias, lo he probado y funciona, lo he aplicado a mi función para entenderlo todo bien. Y ya funciona.

Lo que me comentas de los NULL, esta puesto así porque estaba haciendo pruebas.

Gracias por la solución de la otra función, yo estube probando con el CASE y como no me salía por eso lo puse en una SELECT, ya sabía que no era la mejor solución pero fue lo único que se me ocurrió.

Gracias.
  #27 (permalink)  
Antiguo 08/03/2011, 06:51
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, 4 meses
Puntos: 2658
Respuesta: Resultado null de una select en un procedimiento almacenado

Me alegro que te haya servido todo el tema.
Saludos

:adio:
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: null, procedimiento, select, resultados, almacenar
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 07:16.