 |
Hola tengo este cursor pero se lleva mucho tienpo de ejecución; ¿Como puedo optimizarlo?
vfecha DATE;--AGREGADO VMRP 18/01/2006
CURSOR C_CONTRATOS IS SELECT /* +ALL_ROWS*/ PC.NNO_CLIENTE NCLIENTE, PC.VCVE_PERIODO PERIODO, PC.NPRIMER_DIA PRIMER_DIA, PC.NSEGUNDO_DIA SEGUNDO_DIA, PC.DDIA_GENERACION DIA_GENERACION, PC.DDIA_ANTERIOR DIA_ANTERIOR FROM SET_TPERIODOS_CONTRATOS PC WHERE TRUNC(PC.DDIA_GENERACION) <= vfecha;--TRUNC(SYSDATE) MODIFICADO VMRP 18/01/2006 /* AND EXISTS ( SELECT 1 FROM CLIENTES_CONTRATOS CC WHERE CC.CLI_NO_CLIENTE = PC.NNO_CLIENTE AND CC.VALIDADO = 'S' AND (CC.FECHA_FIN IS NULL OR TRUNC(CC.FECHA_FIN) > TRUNC(SYSDATE))); */ -- MOD. 001 v_ctOrdenes NUMBER; v_ctTxOk NUMBER; v_ctTxAn NUMBER; v_TotTx NUMBER; v_sucursal SUCURSALES.no_sucursal%TYPE; v_domicilio NUMBER; v_folio NUMBER; v_serie VARCHAR2(3); v_dia NUMBER; v_siguienteDia DATE; v_diaAux NUMBER; v_mesAux NUMBER; v_anAux VARCHAR2(2);
BEGIN
/***** BLOQUE AGREGADO VMRP 18/01/2006 ***/ vfecha := TRUNC(SYSDATE); /***** FIN BLOQUE AGREGADO VMRP 18/01/2006 ***/
FOR CCON IN C_CONTRATOS LOOP BEGIN
/* * 1.1.1 CANTIDAD DE ORDENES DE COBRO POR INCLUIR AL ESTADO DE CUENTA * */ SELECT /*+all_rows*/ SUM(cantidad) INTO v_ctOrdenes FROM (SELECT /*+all_rows*/ COUNT(*) cantidad FROM SET_TORDENES_COBRO OC, SET_TCARGOS_COBROS CA, CLIENTES_CONTRATOS CC WHERE OC.NNO_EDO_CUENTA IS NULL AND CA.NIMPORTE > 0 AND OC.VPAGADA = 'S' AND OC.DFECHA_EMISION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')/*agregado VRMP 18/01/2006*/ AND OC.NNO_COBRO = CA.NNO_COBRO AND OC.VSERIE = CA.VSERIE AND OC.NNO_CONTRATO = CC.NO_CONTRATO AND CC.CLI_NO_CLIENTE= CCON.NCLIENTE UNION ALL SELECT /*+all_rows*/ COUNT(*) cantidad FROM SET_TORDENES_COBRO OC, SET_TCARGOS_COBROS CA, CLIENTES_CONTRATOS CC WHERE OC.NNO_EDO_CTA_C IS NULL AND CA.NIMPORTE > 0 AND OC.VPAGADA = 'S' AND OC.DFECHA_CANCELACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')/*agregado VRMP 18/01/2006*/ AND OC.VSERIE = CA.VSERIE AND OC.NNO_CONTRATO = CC.NO_CONTRATO AND CC.CLI_NO_CLIENTE = CCON.NCLIENTE AND OC.NNO_COBRO = CA.NNO_COBRO ); --mod.001
/* * 1.1.2 CANTIDAD DE TRANSACCIONES DEL CLIENTE QUE AUN NO ESTAN INCLUIDOS EN ESTADOS DE CUENTA * */ SELECT /*+ INDEX(CM CMO_PK)*/ COUNT(*) INTO v_ctTxOk --MOD. 001. FROM CUENTAS_MOVIMIENTOS CM, CUENTAS C WHERE CM.NNO_EDO_CUENTA IS NULL AND CM.TMO_CVE_MOVIMIENTO IN ('DGA','DEV','ARS') AND CM.FECHA_CONCILIACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss') -- Mod. 003. AND CM.TE_CVE_ESTADO <> 'TED' AND CM.CUE_NO_CUENTA = C.NO_CUENTA AND CM.CUE_BAN_CVE_BANCO = C.BAN_CVE_BANCO AND C.CHB_CLI_NO_CLIENTE = CCON.NCLIENTE;
/* * 1.1.2.6 TRANSACCIONES ANOMALAS * */ SELECT /*+ ALL_ROWS*/ COUNT(*) INTO v_ctTxAn FROM SET_TCUENTAS_MOV_ANOMALIAS AN, CUENTAS C WHERE AN.NNO_EDO_CUENTA IS NULL AND AN.NCVE_ANOMALIA NOT IN (4,5) AND AN.TMO_CVE_MOVIMIENTO IN ('DEV','DGA') /*agregado VRMP 18/01/2006*/ AND AN.FECHA_CONCILIACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')/* Mod. 003.*/ AND AN.CUE_NO_CUENTA = C.NO_CUENTA AND AN.CUE_BAN_CVE_BANCO = C.BAN_CVE_BANCO AND C.CHB_CLI_NO_CLIENTE = CCON.NCLIENTE;
v_TotTx := v_ctOrdenes + v_ctTxOk + v_ctTxAn; IF v_TotTx > 0 THEN /* * 1.2.1 OBTENER LA SUCURSAL DE FACTURACION * */ /** sE MODIFICA LA obtencion del dato VMRP 18/1/2006*/ /* SELECT UB.RUT_SUC_NO_SUCURSAL, DF.NO_DOMICILIO INTO v_sucursal, v_domicilio FROM UBICACIONES UB, DOMICILIOS_FISCALES DF WHERE DF.UBI_NO_UBICACION = UB.NO_UBICACION AND DF.CLI_NO_CLIENTE = CCON.NCLIENTE AND DF.INACTIVO = 'N' AND ROWNUM = 1;*/
SELECT /*+ALL_ROWS*/UB.RUT_SUC_NO_SUCURSAL, DF.NO_DOMICILIO INTO v_sucursal, v_domicilio FROM UBICACIONES UB, DOMICILIOS_FISCALES DF, SET_TDOMICILIOS_EDO_CUENTA domedo WHERE domedo.nno_cliente = DF.CLI_NO_CLIENTE AND domedo.ndomicilio_fiscal= df.no_domicilio AND DF.UBI_NO_UBICACION = UB.NO_UBICACION AND domedo.NNO_CLIENTE = CCON.NCLIENTE -- AND DF.INACTIVO = 'N' AND ROWNUM = 1;
/* * 1.2.2 CAMBIAR LA SUCURSAL DEL USUARIO * */ /* UPDATE EMPLEADOS SET SUC_NO_SUCURSAL = v_sucursal WHERE NO_EMPLEADO IN ( SELECT VALOR FROM PARAMETROS WHERE CVE_PARAMETRO = 'EEC');*/
/* * 1.2.3 OBTENER FOLIO Y SERIE * */ v_folio := Pkg_Obten.FOLIO_DOCTO('ECC', v_serie,v_sucursal);
/* * 1.2.4 REGISTRAR EL ESTADO DE CUENTA * */
INSERT INTO SET_TESTADOS_CUENTA ( NNO_EDO_CUENTA, VSERIE, NNO_CLIENTE, DFECHA_GENERACION, DFECHA_INICIO, DFECHA_FIN, VIMPRESO, NSUCURSAL, NDOMICILIO_FISCAL) VALUES( v_folio,v_serie,CCON.NCLIENTE,SYSDATE,(CCON.DIA_ANTERIOR +1), TRUNC(CCON.DIA_GENERACION),/*TRUNC(SYSDATE), Modificado VMRP 18/01/2006 */ 'N',v_sucursal,v_domicilio );
/* * 1.2.5 ACTUALIZA LAS ORDENES DE COBRO DEL CLIENTE * */ UPDATE SET_TORDENES_COBRO SET NNO_EDO_CUENTA = v_folio, VSERIE_EDO_CUENTA = v_serie WHERE NNO_EDO_CUENTA IS NULL AND NIMPORTE_TOTAL > 0 AND DFECHA_EMISION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')--agregado VRMP 18/01/2006 AND VPAGADA = 'S' -- mod. 001 AND NNO_CONTRATO IN ( SELECT NO_CONTRATO FROM CLIENTES_CONTRATOS CC WHERE CC.NO_CONTRATO = NNO_CONTRATO AND CC.CLI_NO_CLIENTE = CCON.NCLIENTE);
/* * 1.2.5.1 ACTUALZA LAS ORDENES DE COBRO CANCELADAS DEL CLIENTE mod. 001 * */ UPDATE SET_TORDENES_COBRO SET NNO_EDO_CTA_C = v_folio, VSERIE_EDO_CTA_C = v_serie WHERE NNO_EDO_CTA_C IS NULL AND NIMPORTE_TOTAL > 0 AND DFECHA_CANCELACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')--agregado VRMP 18/01/2006 AND VPAGADA = 'S' AND NNO_CONTRATO IN ( SELECT NO_CONTRATO FROM CLIENTES_CONTRATOS CC WHERE CC.NO_CONTRATO = NNO_CONTRATO AND CC.CLI_NO_CLIENTE = CCON.NCLIENTE);
/* * 1.2.6 ACTUALIZAMOS LAS TRANSACCIONES OK CON EL FOLIO Y LA SERIE DEL ESTADO DE CUENTA MOD. 001 * */ UPDATE /*+ INDEX(CM CMO_PK)*/ CUENTAS_MOVIMIENTOS CM SET CM.NNO_EDO_CUENTA = v_folio, CM.VSERIE = v_serie WHERE CM.NNO_EDO_CUENTA IS NULL AND CM.TMO_CVE_MOVIMIENTO IN ('DGA','DEV','ARS') -- AND CM.FECHA_MOVIMIENTO <= to_date(to_char(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')--agregado VRMP 18/01/2006 AND CM.FECHA_CONCILIACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss')-- Mod. 003. AND CM.TE_CVE_ESTADO <> 'TED' AND (CM.CUE_NO_CUENTA,CM.CUE_BAN_CVE_BANCO) IN ( SELECT /*+ALL_ROWS*/ NO_CUENTA,BAN_CVE_BANCO FROM CUENTAS C WHERE C.NO_CUENTA = CM.CUE_NO_CUENTA AND C.BAN_CVE_BANCO = CM.CUE_BAN_CVE_BANCO AND C.CHB_CLI_NO_CLIENTE = CCON.NCLIENTE);
UPDATE SET_TCUENTAS_MOV_ANOMALIAS AN SET AN.NNO_EDO_CUENTA = v_folio, AN.VSERIE = v_serie WHERE AN.NNO_EDO_CUENTA IS NULL AND (CUE_NO_CUENTA,CUE_BAN_CVE_BANCO) IN ( SELECT /*ALL_ROWS*/ NO_CUENTA,BAN_CVE_BANCO FROM CUENTAS C WHERE AN.NCVE_ANOMALIA NOT IN (4,5) AND AN.TMO_CVE_MOVIMIENTO IN ('DGA','DEV')/*agregado VRMP 18/01/2006*/ AND AN.FECHA_CONCILIACION <= TO_DATE(TO_CHAR(ccon.dia_generacion,'dd/mm/yyyy')||' 23:59:59','dd/mm/yyyy hh24:mi:ss') AND C.NO_CUENTA = AN.CUE_NO_CUENTA AND C.BAN_CVE_BANCO = AN.CUE_BAN_CVE_BANCO AND C.CHB_CLI_NO_CLIENTE = CCON.NCLIENTE);--Mod. 003.
END IF;
SELECT /*+ALL_ROWS*/ TO_NUMBER(TO_CHAR(SYSDATE,'DD')) INTO v_dia FROM DUAL; IF CCON.PERIODO = 'MEN' THEN v_siguienteDia := CCON.DIA_GENERACION; -- v_siguienteDia := ADD_MONTHS(CCON.DIA_GENERACION,1); LOOP v_siguienteDia := ADD_MONTHS(v_siguienteDia,1); IF TO_NUMBER(TO_CHAR(v_siguienteDia,'MM')) = 2 THEN IF CCON.PRIMER_DIA IN (29,30,31) THEN v_siguienteDia := LAST_DAY(v_siguienteDia); ELSE v_siguienteDia := DATE(CCON.PRIMER_DIA||'/'||TO_CHAR(v_siguienteDia,'mm')||'/'||TO_CHAR(v_siguienteDia,'yy'),'dd/mm/yy'); END IF; ELSE IF CCON.PRIMER_DIA = 31 THEN v_siguienteDia := LAST_DAY(v_siguienteDia); ELSE v_siguienteDia := DATE(CCON.PRIMER_DIA||'/'||TO_CHAR(v_siguienteDia,'mm')||'/'||TO_CHAR(v_siguienteDia,'yy'),'dd/mm/yy'); END IF; END IF; IF TRUNC(v_siguienteDia) > TRUNC(SYSDATE) THEN EXIT; END IF; END LOOP; ELSE IF CCON.PERIODO = 'QNL' THEN IF CCON.PRIMER_DIA > v_dia OR (v_dia >= CCON.PRIMER_DIA AND v_dia >= CCON.SEGUNDO_DIA) THEN v_diaAux := CCON.PRIMER_DIA; v_mesAux := TO_NUMBER(TO_CHAR(ADD_MONTHS(CCON.DIA_GENERACION,1),'MM')); v_anAux := TO_CHAR(ADD_MONTHS(CCON.DIA_GENERACION,1),'YY'); ELSE v_diaAux := CCON.SEGUNDO_DIA; v_mesAux := TO_NUMBER(TO_CHAR(CCON.DIA_GENERACION,'MM')); v_anAux := TO_CHAR(CCON.DIA_GENERACION,'YY'); END IF; IF v_diaAux = 31 OR (v_diaAux = 30 OR v_diaAux = 29 AND v_mesAux = 2) THEN v_diaAux := TO_NUMBER(TO_CHAR(LAST_DAY(TO_DATE(v_mesAux||'/'||v_anAux,'MM/YY')),'DD')); END IF; v_siguienteDia := TO_DATE(v_diaAux||'/'||v_mesAux||'/'||v_anAux||' 00:00:00','DD/MM/YY HH24:MI:SS'); ELSE v_siguienteDia := TRUNC(SYSDATE)+1; LOOP IF TO_NUMBER(TO_CHAR(v_siguienteDia,'D')) = CCON.PRIMER_DIA THEN EXIT; END IF; v_siguienteDia := v_siguienteDia + 1; END LOOP; END IF; END IF;
UPDATE SET_TPERIODOS_CONTRATOS SET DDIA_GENERACION = v_siguienteDia, DDIA_ANTERIOR = TRUNC(CCON.DIA_GENERACION)--TRUNC(SYSDATE) Modifcado VMRP 18/01/2006 WHERE NNO_CLIENTE = CCON.NCLIENTE;
COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('Cliente ->'||CCON.NCLIENTE||' error:'||SQLERRM); END;
END LOOP;
/*EXCEPTION WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('error:'||SQLERRM);*/ END Proc_Genera_Estado_Cuenta; /
|