Estimados Amigos:
Tengo dos tablas de una base de datos MySQL, una de ellas tiene datos sobre las cuotas sociales de un afiliado a una mutual, y la otra tiene un registro de pagos de estas cuotas sociales. Ej:
Tabla CuotasSociales.
ID Fecha pura saldo interes importepag Pagada Mes Af_Id
1 27/01/2012 0.000 0.000 0.000 59.000 1 Dec 2
2 27/01/2012 0.000 34.910 0.000 24.090 2 Dec 3
Tabla Planillas.
Af_ID Valor Periodo
2 59.000 Dec
3 24.090 Dec
Aproximadamente son 2000 registros en ambas tablas.
Lo que necesito hacer es actualizar los datos de la tabla CuotasSociales con los datos de la tabla planilla, Pues anteriormente se inserto los registros mediante un procedimiento almacenado que inserta un valor (59,000 pesos, valor de la cuota social) en el campo importepag y un '1' en el campo pagada, valor que representa el pago total de la cuota(reg. N°1), la otra posibilidad es como se muestra en el reg. N°2, si el pago fue menor a 59 pesos, se inserta el valor pagado(24.090 pesos ) en el campo importepag y la diferencia respecto a 59 se ingresa en el campo saldo, se coloca un '2' en el campo pagada que representa un pago parcial.
Los valores de la tabla planillas son extraidos de los descuentos por planillas de los afiliados.
Código SQL
[-]
CREATE DEFINER = 'root'@'localhost' PROCEDURE `cuotasmutual828`()
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
#Routine body goes here...
DECLARE dni VARCHAR(8);
DECLARE control VARCHAR(15);
declare importe DECIMAL(18,3);
DECLARE operacion int;
DECLARE afiliado int;
DECLARE diff DECIMAL(18,3);
DECLARE done INT DEFAULT 0;
DECLARE cuotasocial DECIMAL(18,3);
DECLARE bPlanillas CURSOR FOR SELECT
planillas.dni,
planillas.control,
planillas.importe,
afiliados.id as afiliado
FROM
planillas
INNER JOIN afiliados ON (planillas.dni = afiliados.dni)order by dni;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN bPlanillas;
set operacion = 1680;
SELECT cuota_social INTO cuotasocial FROM parametros WHERE id = 1;
REPEAT
FETCH bPlanillas INTO dni, control, importe, afiliado;
IF NOT done THEN
if importe >= cuotasocial THEN
INSERT INTO cuotassociales (fecha,pura,saldo,interes,importepag,pagada,mespagado,anopagado,operacion,afiliados_id,modocobranzas _id)
VALUES ( curdate(),0,0,0,importe,'1','Dec','2012',operacion,afiliado,'1');
ELSE
set diff = cuotasocial - importe;
INSERT INTO cuotassociales (fecha,pura,saldo,interes,importepag,pagada,mespagado,anopagado,operacion,afiliados_id,modocobranzas _id)
VALUES ( curdate(),0,diff,0,importe,'2','Dec','2012',operacion,afiliado,'1');
END IF;
set operacion = operacion + 1;
END IF;
UNTIL done END REPEAT;
CLOSE bPlanillas;
END;
Este procedimiento almacenado funciona bien, aunque demora en promedio 43seg. aprox., pero funciona.
Despues de correr este procedimiento , se limpia la tabla planilla y se cargan nuevos datos que representan descuentos por otras modalidades por ej. descuentos por CBU, obviamente dentro del mismo periodo.
Como dije arriba debo actualizar la tabla cuotassociales con estos nuevos datos de la tabla planillas. y aqui recide el problema que se me presenta.
La logica de la actualizacion seria la siguiente:
1. tomar un registro de la tabla planillas, ver si existe el afiliado en la tabla cuotassociales.
2. si existe comprobar que el saldo sea mayor que cero ( es decir que este parcialmente pagada la cuota). actualizar el importepag y el campo pagada en '1' si la suma es igual a 59 o seguir con el valor '2' si aun es menor que 59.
3. Seguir los pasos 1 y 2 hasta el ultimo registro de la tabla planillas.
Este es el procedimiento almacenado que intentar hacer esto.
Código SQL
[-]
CREATE DEFINER = 'root'@'localhost' PROCEDURE `cuotasmutual964`()
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
#Routine body goes here...
#Routine body goes here...
DECLARE dni VARCHAR(8);
DECLARE control VARCHAR(15);
DECLARE importe DECIMAL(18,3);
DECLARE operacion int;
DECLARE afiliado int;
DECLARE diff DECIMAL(18,3);
DECLARE done INT DEFAULT 0;
DECLARE diff_ DECIMAL(18,3);
DECLARE cid int;
DECLARE cfecha VARCHAR(10);
DECLARE cpura DECIMAL(18,3);
DECLARE csaldo DECIMAL(18,3);
DECLARE cinteres DECIMAL(18,3);
DECLARE cimportepag DECIMAL(18,3);
DECLARE cpagada int ;
DECLARE cmespagado VARCHAR(3);
DECLARE canopagado VARCHAR(4);
DECLARE coperacion INT;
DECLARE cafiliados_id INT;
DECLARE cmodocobranzas_id INT;
DECLARE cdni VARCHAR(8);
DECLARE bPlanillas CURSOR FOR SELECT
planillas.dni,
planillas.control,
planillas.importe,
afiliados.id as afiliado
FROM
planillas
INNER JOIN afiliados ON (planillas.dni = afiliados.dni)order by dni;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN bPlanillas;
REPEAT
FETCH bPlanillas INTO dni, control, importe, afiliado;
IF NOT done THEN
SELECT
cuotassociales.id,
cuotassociales.pura,
cuotassociales.saldo,
cuotassociales.interes,
cuotassociales.importepag,
cuotassociales.pagada,
cuotassociales.afiliados_id,
cuotassociales.modocobranzas_id,
afiliados.dni
INTO
cid,
cpura,
csaldo,
cinteres,
cimportepag,
cpagada,
cafiliados_id,
cmodocobranzas_id,
cdni
FROM
cuotassociales
INNER JOIN afiliados ON afiliados.id = cuotassociales.afiliados_id
WHERE afiliados.dni = dni limit 1;
IF csaldo > 0 THEN
IF importe >= csaldo THEN
SET diff = importe - csaldo;
UPDATE cuotassociales SET
importepag = cimportepag + csaldo,
pagada = '5'
WHERE id = cid;
ELSE
SET diff = 0;
SET diff_ = csaldo - importe;
UPDATE cuotassociales SET
saldo = diff_,
interes = 0,
importepag = cimportepag + importe,
pagada = '9'
WHERE id = cid;
END IF;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE bPlanillas;
END;
pero me actualiza solo un registro. lo que he notado es que cuando el select dentro del repeat es nulo, directamente la variable done se pone a 1 y sale del bucle y termina el procedimiento.
Uso como lenguaje anfitrion el PHP 5.3, pero hice ejecutar estos procedimiento con los clientes de MySQL: Navicat y EMS mysqlmanager.
Sinceramente no se como modificar este procedimiento para que actualice todos los registro que correspondan.
Gracias por su tiempo.
Saludos.