Page 1 of 1

OT: ayuda con store procedure mysql (solucionado)

PostPosted: Mon Jan 20, 2014 10:04 pm
by carlos vargas
amigos, solicito su ayuda con este store procedure de mysql,
no me esta funcionando con el parametro tipo fecha, pero si cambio el parametro del select
a esto un literal como esto
WHERE A.FECHA = '2013-11-25' );

si funciona
Code: Select all  Expand view

PROCEDURE `CERRAR_CobroDia`(IN `dFechaCierre` DATE )
BEGIN

   DECLARE bContinuar BOOLEAN DEFAULT TRUE;
   
    DECLARE nNUM_PRES, nNUM_ZONA, nNUM_RUTA, nNUM_CIUD, nNUM_CLIE INTEGER DEFAULT 0;
    DECLARE dFECHA, dFECHA_INI, dFECHA_FIN DATE DEFAULT 0;
    DECLARE nPLAZO, nNUM_CUOTAS INTEGER DEFAULT 0;
    DECLARE nABONO, nTOTAL, nVAL_CUOTA, nSALDO FLOAT DEFAULT 0;
    DECLARE nINTE_TASA, nMANT_TASA, nDESE_TASA FLOAT DEFAULT 0;                                

    DECLARE nABONO_I, nABONO_D, nABONO_M FLOAT DEFAULT 0;
        DECLARE nI_ABONO, nP_ABONO FLOAT DEFAULT 0;
        DECLARE nSALDO_I, nSALDO_F FLOAT DEFAULT 0;
        DECLARE nSALDO_F_I, nSALDO_F_D, nSALDO_F_M FLOAT DEFAULT 0;
        DECLARE nI_SALDO_F, nP_SALDO_F FLOAT DEFAULT 0;

    DECLARE cobrodia CURSOR FOR (   
        SELECT A.NUM_PRES, A.FECHA, A.ABONO,
        B.NUM_CIUD, B.NUM_CLIE, B.TOTAL, B.PLAZO, B.NUM_CUOTAS, B.VAL_CUOTA, B.SALDO, B.FECHA_INI, B.FECHA_FIN,
        B.INTE_TASA, B.MANT_TASA, B.DESE_TASA,
        C.NUM_ZONA, D.NUM_RUTA
        FROM DCOBROSXRUTA AS A
        INNER JOIN PRESTAMOS AS B ON A.NUM_PRES=B.NUM_PRES
        INNER JOIN CIUDADES  AS C ON B.NUM_CIUD=C.NUM_CIUD
        INNER JOIN CLIENTES  AS D ON B.NUM_CLIE=D.NUM_CLIE
        WHERE A.FECHA = dFechaCierre );
                               
   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET bContinuar = FALSE;

    DECLARE exit handler for sqlexception
    BEGIN
        ROLLBACK;
    END;
 
    DECLARE exit handler for sqlwarning
    BEGIN
        ROLLBACK;
    END;

    SET bContinuar = TRUE;
   
        OPEN cobrodia;

         START TRANSACTION;
   
    REPEAT
           
    FETCH cobrodia INTO nNUM_PRES, dFECHA, nABONO,
                                nNUM_CIUD, nNUM_CLIE, nTOTAL, nPLAZO, nNUM_CUOTAS, nVAL_CUOTA, nSALDO, dFECHA_INI, dFECHA_FIN,
                                    nINTE_TASA, nMANT_TASA, nDESE_TASA,
                                    nNUM_ZONA, nNUM_RUTA;
                                       
        IF bContinuar THEN

         SET nABONO_I   = ( nINTE_TASA / 100 ) * nABONO;
         SET nABONO_D   = ( nDESE_TASA / 100 ) * nABONO;
         SET nABONO_M   = ( nMANT_TASA / 100 ) * nABONO;
         SET nI_ABONO   = nABONO_I + nABONO_D + nABONO_M;
         SET nP_ABONO   = nABONO - nI_ABONO;
            SET nSALDO_F   = nSALDO_I - nABONO;
            SET nSALDO_F_I = ( nINTE_TASA / 100 ) * nSALDO_F;
         SET nSALDO_F_D = ( nDESE_TASA / 100 ) * nSALDO_F;
         SET nSALDO_F_M = ( nMANT_TASA / 100 ) * nSALDO_F;
         SET nI_SALDO_F = nSALDO_F_I + nSALDO_F_D + nSALDO_F_M;
         SET nP_SALDO_F = nSALDO_F - nI_SALDO_F;
                           
            INSERT INTO COBROXDIA
                ( NUM_ZONA, NUM_CIUD, NUM_RUTA, NUM_CLIE, NUM_PRES,
                  PLAZO, VAL_CUOTA,
                  FECHA_INI, FECHA_FIN, FECHA,
                  ABONO, SALDO_I,
                  ABONO_I, ABONO_D, ABONO_M,
                  I_ABONO, P_ABONO,
                  SALDO_F,
                  SALDO_F_I, SALDO_F_D, SALDO_F_M,
                  I_SALDO_F, P_SALDO_F )  
                VALUES
                ( nNUM_ZONA, nNUM_CIUD, nNUM_RUTA, nNUM_CLIE, nNUM_PRES,
                  nPLAZO, nVAL_CUOTA,
                  dFECHA_INI, dFECHA_FIN, dFECHA,
                  nABONO, nSALDO_I,
                  nABONO_I, nABONO_D, nABONO_M,
                  nI_ABONO, nP_ABONO,
                  nSALDO_F,
                  nSALDO_F_I, nSALDO_F_D, nSALDO_F_M,
                  nI_SALDO_F, nP_SALDO_F );

            INSERT INTO MOVIMIENTOS
                ( NUM_PRES, NUM_CLIE, FECHA, HABER, SALDO )
                VALUES
                ( nNUM_PRES, nNUM_CLIE, dFECHA, nABONO, nSALDO - nABONO );

            UPDATE PRESTAMOS    
                SET SALDO=SALDO-nABONO
                WHERE NUM_PRES=nNUM_PRES;
                   
        END IF;
   
    UNTIL bContinuar=FALSE END REPEAT;

    UPDATE COBROXDIAC A     
        SET A.CERRADO=TRUE
        WHERE A.FECHA=dFechaCierre;  
   
   COMMIT;

    CLOSE cobrodia;

END
 

Re: OT: ayuda con store procedure mysql

PostPosted: Mon Jan 20, 2014 10:11 pm
by horacio
No quiero decir un dislate pero me parece que las fechas MySql las trata como un string. De hecho en mis aplicaciones tengo una rutina para estos menesteres.

Saludos

Re: OT: ayuda con store procedure mysql

PostPosted: Mon Jan 20, 2014 10:33 pm
by carlos vargas
?? no entendi la respuesta :-(, se que mysql trata las fecha como texto.

yo llamo al sp asi

Code: Select all  Expand view
CALL CERRAR_CobroDia('2013-11-25')


al ser el parametro de la funcion IN `dFechaCierre` DATE

y compararse contra un campo fecha penso que no deberia fallar

Code: Select all  Expand view
WHERE A.FECHA = dFechaCierre


pero falla.

si cambio internamente en el sp asi
Code: Select all  Expand view
WHERE A.FECHA = '2013-11-25'


si funciona, por que ?

Re: OT: ayuda con store procedure mysql

PostPosted: Mon Jan 20, 2014 11:40 pm
by Kleyber
Mi amigo Carlos,

Intenta con esto:

Code: Select all  Expand view

PROCEDURE `CERRAR_CobroDia`(IN dFechaCierre DATE )
 

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 3:37 am
by carlos vargas
no funciona kleyber, esa fue mi primera opcion, es mas he notado en la depuracion de sp que las variables tipo date no toman datos en el fetch, si no uqe muestran '0000-00-00' donde las variables enteras y float tomas los datos correctamente.
Image

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 1:22 pm
by Hector Pedro Lerda
Carlos buen dia

Prueba de esta manera

WHERE A.FECHA = ' +"'"dtos( dFechaCierre)+"'"

Saludos Pedro

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 1:24 pm
by Hector Pedro Lerda
Carlos disculpa me olvide un signo +


WHERE A.FECHA = ' +"'"+dtos( dFechaCierre)+"'"

Saludos Pedro

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 5:24 pm
by carlos vargas
lamentablemente no se puede, ya que todo este codigo esta enteramente en el store procedure, y creo que la funcion ctod de propia de harbour.

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 5:48 pm
by Francisco Horta
Carlos

prueba asi:
WHERE A.FECHA = ' " + (dFechaCierre + 0) + " ' "

si recuerdo creo que debe retornar el equalente a convertir con DTOS()
si pruebas SELECT curdate() -> '2014-0-21'
y asi SELECT curdate() + 0 -> 20140121

saludos
paco

Re: OT: ayuda con store procedure mysql

PostPosted: Tue Jan 21, 2014 9:37 pm
by carlos vargas
Pues los tiros ni cerca pasaba. :-)
me tomo dia y medio encontrar la solucion.

sucede que al ejecutarse el store procedure se disparaban unos warning y como esta definido que ante un warning se dispare el rollback asi como ante un error, pues se deshacía todo, y no aparecía ningún dato.

los warning eran por que las variables declaradas eran double, y como las columnas de los datos eran decimal(10,2) pues algunos datos se truncaban.
para corregilo use cast.

mil gracias por sus ideas amigos, pongo el código para futura revisión.

Code: Select all  Expand view

CREATE DEFINER=`carlos`@`%` PROCEDURE `CERRAR_CobroDia`(IN `dFechaCerrar` DATE)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

   DECLARE bContinuar BOOLEAN DEFAULT TRUE;
   
    DECLARE nNUM_ZONA, nNUM_CIUD, nNUM_RUTA, nNUM_CLIE, nNUM_PRES, nPLAZO, nNUM_CUOTAS INT DEFAULT 0;
    DECLARE nVAL_CUOTA DOUBLE DEFAULT 0;
    DECLARE dFECHA, dFECHA_INI, dFECHA_FIN DATE DEFAULT '0000-00-00';
    DECLARE nTOTAL, nABONO, nSALDO DOUBLE DEFAULT 0;
   
    DECLARE nINTE_TASA, nMANT_TASA, nDESE_TASA DOUBLE DEFAULT 0;
    DECLARE nABONO_I, nABONO_D, nABONO_M DOUBLE DEFAULT 0;
    DECLARE nI_ABONO, nP_ABONO, nSALDO_F DOUBLE DEFAULT 0;
    DECLARE nSALDO_F_I, nSALDO_F_D, nSALDO_F_M DOUBLE DEFAULT 0;
    DECLARE nI_SALDO_F, nP_SALDO_F DOUBLE DEFAULT 0;
           
    DECLARE cobrodia CURSOR FOR
        SELECT A.NUM_PRES,
               A.FECHA,
                 A.ABONO,
                 B.NUM_CIUD,
                 B.NUM_CLIE,
                 B.TOTAL,
                 B.PLAZO,
                 B.NUM_CUOTAS,
                 B.VAL_CUOTA,
                 B.SALDO,
                 B.FECHA_INI,
                 B.FECHA_FIN,
                 B.INTE_TASA,
                 B.MANT_TASA,
                 B.DESE_TASA,
                 C.NUM_ZONA,
                 D.NUM_RUTA
        FROM DCOBROSXRUTA  A
        INNER JOIN PRESTAMOS B ON A.NUM_PRES=B.NUM_PRES
        INNER JOIN CIUDADES  C ON B.NUM_CIUD=C.NUM_CIUD
        INNER JOIN CLIENTES  D ON B.NUM_CLIE=D.NUM_CLIE
        WHERE A.FECHA=dFechaCerrar;

   DECLARE CONTINUE HANDLER FOR NOT FOUND SET bContinuar = FALSE;
   
    DECLARE exit handler for sqlexception
    BEGIN
        ROLLBACK;
    END;

    DECLARE exit handler for sqlwarning
    BEGIN
        ROLLBACK;
    END;
       
   OPEN cobrodia;

   START TRANSACTION;

    REPEAT

    FETCH cobrodia INTO nNUM_PRES,
                            dFECHA,
                                  nABONO,
                            nNUM_CIUD,
                                  nNUM_CLIE,
                                  nTOTAL,
                                  nPLAZO,
                                  nNUM_CUOTAS,
                                  nVAL_CUOTA,
                                  nSALDO,
                                  dFECHA_INI,
                                  dFECHA_FIN,
                        nINTE_TASA,
                                  nMANT_TASA,
                                  nDESE_TASA,
                        nNUM_ZONA,
                                  nNUM_RUTA;
               
        IF bContinuar THEN
           
         SET nABONO_I   = ( nINTE_TASA / 100 ) * nABONO         ;
         SET nABONO_D   = ( nDESE_TASA / 100 ) * nABONO         ;
         SET nABONO_M   = ( nMANT_TASA / 100 ) * nABONO         ;
         SET nI_ABONO   = nABONO_I + nABONO_D + nABONO_M        ;
         SET nP_ABONO   = nABONO - nI_ABONO                     ;
            SET nSALDO_F   = nSALDO - nABONO                       ;
            SET nSALDO_F_I = ( nINTE_TASA / 100 ) * nSALDO_F       ;
         SET nSALDO_F_D = ( nDESE_TASA / 100 ) * nSALDO_F       ;
         SET nSALDO_F_M = ( nMANT_TASA / 100 ) * nSALDO_F       ;
         SET nI_SALDO_F = nSALDO_F_I + nSALDO_F_D + nSALDO_F_M  ;
         SET nP_SALDO_F = nSALDO_F - nI_SALDO_F                 ;
         
            INSERT INTO COBROXDIA
                ( NUM_ZONA,
                  NUM_CIUD,
                  NUM_RUTA,
                  NUM_CLIE,
                  NUM_PRES,
                  PLAZO,
                  VAL_CUOTA,
                  FECHA_INI,
                  FECHA_FIN,
                  FECHA,
                  ABONO,
                  SALDO_I,
                  ABONO_I,
                  ABONO_D,
                  ABONO_M,
                  I_ABONO,
                  P_ABONO,
                  SALDO_F,
                  SALDO_F_I,
                  SALDO_F_D,
                  SALDO_F_M,
                  I_SALDO_F,
                  P_SALDO_F,
                  TOTAL )
                VALUES
                ( nNUM_ZONA ,
                  nNUM_CIUD ,
                  nNUM_RUTA ,
                  nNUM_CLIE ,
                  nNUM_PRES ,
                  nPLAZO    ,
                  cast( nVAL_CUOTA AS DECIMAL(10,2) ),
                  dFECHA_INI,
                  dFECHA_FIN,
                  dFECHA    ,
                  cast( nABONO     AS DECIMAL(10,2) ),
                  cast( nSALDO     AS DECIMAL(10,2) ),
                  cast( nABONO_I   AS DECIMAL(10,2) ),
                  cast( nABONO_D   AS DECIMAL(10,2) ),
                  cast( nABONO_M   AS DECIMAL(10,2) ),
                  cast( nI_ABONO   AS DECIMAL(10,2) ),
                  cast( nP_ABONO   AS DECIMAL(10,2) ),
                  cast( nSALDO_F   AS DECIMAL(10,2) ),
                  cast( nSALDO_F_I AS DECIMAL(10,2) ),
                  cast( nSALDO_F_D AS DECIMAL(10,2) ),
                  cast( nSALDO_F_M AS DECIMAL(10,2) ),
                  cast( nI_SALDO_F AS DECIMAL(10,2) ),
                  cast( nP_SALDO_F AS DECIMAL(10,2) ),
                  cast( nTOTAL     AS DECIMAL(10,2) ) );
           
            INSERT INTO MOVIMIENTOS
                ( NUM_PRES, NUM_CLIE, FECHA, HABER, SALDO )
                VALUES
                ( nNUM_PRES, nNUM_CLIE, dFECHA, nABONO, nSALDO - nABONO );

            UPDATE PRESTAMOS SET SALDO=SALDO-nABONO, ABONADO=ABONADO+nABONO
                WHERE NUM_PRES=nNUM_PRES;
           
            UPDATE PRESTAMOS SET PAGADO=TRUE   
                WHERE NUM_PRES=nNUM_PRES AND SALDO<=0;
               
        END IF;

    UNTIL bContinuar=FALSE END REPEAT;

    UPDATE COBROXDIAC SET CERRADO=FALSE WHERE FECHA=dFechaCerrar;

    CLOSE cobrodia;
   
    COMMIT;

END
 

Re: OT: ayuda con store procedure mysql (solucionado)

PostPosted: Tue Jan 21, 2014 9:42 pm
by carlos vargas
Joder, que bueno esto del store procedure, este proceso tomaba su minuto en ads, con tdolphi y codificado tomaba un poco mas, pero en store procedure toma menos de 4 segundo.

Re: OT: ayuda con store procedure mysql (solucionado)

PostPosted: Tue Jan 21, 2014 10:11 pm
by Daniel Garcia-Gil
Carlos

Los store procedure/function son adictivos, pero hay que tener cuidado a la hora de concurrencias pues el tiro puede salir mal en rendimiento del servidor

Re: OT: ayuda con store procedure mysql (solucionado)

PostPosted: Wed Jan 22, 2014 12:39 am
by carlos vargas
He tomado nota, daniel. gracias por el tips