Ver Mensaje Individual
  #25 (permalink)  
Antiguo 04/03/2011, 07:27
Avatar de gnzsoloyo
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: 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