create or replace
PROCEDURE SP_ZZ_PARCE
IS
V_CTR ZZ_PARCE.NM_CONTRAT%TYPE;
V_LIB ZZ_PARCE.NM_LIBERAC%TYPE;
V_PARCE ZZ_PARCE.NM_PARCELA%TYPE;
V_CONTADOR ZZ_PARCE.CONTADOR%TYPE;
V_TEMP ZZ_PARCE.TEMP%TYPE := 0;
CURSOR C_PRINCIPAL
IS SELECT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,CONTADOR,TEMP
FROM ZZ_PARCE;
BEGIN
OPEN C_PRINCIPAL;
--FETCH C_PRINCIPAL INTO V_CTR,V_LIB,V_PARCE,V_SITUACAO,V_TEMP;
LOOP
FETCH C_PRINCIPAL INTO V_CTR,V_LIB,V_PARCE,V_CONTADOR,V_TEMP;
IF C_PRINCIPAL%NOTFOUND THEN
EXIT;
END IF;
IF(V_CONTADOR = 1 ) THEN
V_TEMP := V_TEMP + 1;
UPDATE ZZ_PARCE SET TEMP = V_TEMP;
END IF;
END LOOP;
COMMIT;
CLOSE C_PRINCIPAL;
END SP_ZZ_PARCE;
POREM ELA NÃO ESTÁ ATUALIZANDO NO BD.
O QUE SERIA?
Cara se teu select esta trazendo resultados e o contador é igual a 1 pelo menos uma vez então tenta colocar o teu comit dentro do loop logo após o update.
Outra coisa, o teu update esta sem clausula where.
Pode estar acontecendo de ele atualizar todos os registros com o mesmo valor anterior pois no ultimo registro que atendeu a condição do teu if o valor de temp era exatamente o mesmo que estava antes do primeiro update.
Isso mesmo, fiz um debug e verifiquei que ele estava perdendo conexão no update.
Então agora coloquei o where e estou esperando rodar para ver no que dá.
for i in (SELECT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,CONTADOR,TEMP FROM ZZ_PARCE) LOOP
IF (i.CONTADOR=1) THEN
UPDATE ZZ_PARCE SET TEMP = i.TEMP WHERE NM_CONTRAT=i.NM_CONTRAT;
END IF;
END LOOP;
DECLARE
BEGIN
FOR i IN (SELECT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,CONTADOR,TEMP FROM ZZ_PARCE_TEMP) LOOP
IF (i.CONTADOR = 1) THEN
UPDATE ZZ_PARCE_TEMP
SET TEMP = i.TEMP + TEMP
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC;
ELSE IF (i.CONTADOR = 0) THEN
WHILE (i.NM_PARCELA >= 1) LOOP
UPDATE ZZ_PARCE_TEMP
SET TEMP = 0
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC;
END LOOP;
END IF;
END IF;
END LOOP;
END;
O problema é que não atualiza todos os registros, e não sei o que está faltando.
1º - CONTADOR sempre será 1 ou 0?
2º - WHILE sem sentido.
3º - NM_PARCELA sempre será maior ou igual a 1?
4º - Usa a tag CODE pra mostrar teu código no fórum.
5º - Executa isso e posta o resultado.
BEGIN
FOR i IN (SELECT NM_CONTRAT,
NM_LIBERAC,
NM_PARCELA,
CONTADOR,
TEMP
FROM ZZ_PARCE_TEMP) LOOP
IF nvl(i.CONTADOR,0) = 1 THEN
UPDATE ZZ_PARCE_TEMP
SET TEMP = i.TEMP + TEMP
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC;
dbms_output.put_line ('Cont = 1 '||i.NM_CONTRAT||' - '||i.NM_LIBERAC);
ELSE IF nvl(i.CONTADOR,0) = 0 AND
nvl(i.NM_PARCELA,1) >= 1 THEN
UPDATE ZZ_PARCE_TEMP
SET TEMP = 0
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC;
dbms_output.put_line ('Cont = 0 '||i.NM_CONTRAT||' - '||i.NM_LIBERAC);
ELSE
dbms_output.put_line ('Não atualizou o registro '||i.NM_CONTRAT||' - '||i.NM_LIBERAC);
END IF;
END LOOP;
END;
Verifica os output, quantos apareceram, veja o porque deles terem ou não atualizado.
DECLARE
EXTRA INT := 0;
BEGIN
FOR i IN (SELECT DISTINCT NM_CONTRAT,NM_LIBERAC FROM ZZ_PARCE_TEMP2) LOOP
EXTRA := 1;
FOR j IN (SELECT DISTINCT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,CONTADOR,TEMP FROM ZZ_PARCE_TEMP2
WHERE NM_CONTRAT = i.NM_CONTRAT AND NM_LIBERAC = i.NM_LIBERAC) LOOP
IF (j.CONTADOR = 1) THEN
UPDATE ZZ_PARCE_TEMP2
SET TEMP = EXTRA
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC
AND CONTADOR = 1;
EXTRA := EXTRA + 1;
ELSE IF(j.CONTADOR != 1) THEN
EXIT;
END IF;
END IF;
END LOOP;
END LOOP;
COMMIT;
END;
O problema está no exit.
Na hora que eu dou exit ele vai para o próximo registro do primeiro cursor, como esperado.
Só que eu quero que ele vá para o próximo contrato do prímeiro cursor não o próximo registro, lembrando que um contrato pode estar duplicado pelo fato de ter mais de uma liberação de contrato.
alguém pode me ajudar?
Mais uma vez...
DECLARE
EXTRA INTEGER;
BEGIN
FOR i IN (SELECT DISTINCT NM_CONTRAT,NM_LIBERAC FROM ZZ_PARCE_TEMP3 ORDER BY NM_CONTRAT, NM_LIBERAC ASC) LOOP
EXTRA := 0;
FOR j IN (SELECT DISTINCT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,TP_SITUACA,CONTADOR,TEMP FROM ZZ_PARCE_TEMP3
WHERE NM_CONTRAT = i.NM_CONTRAT AND NM_LIBERAC = i.NM_LIBERAC
ORDER BY NM_CONTRAT, NM_LIBERAC ASC, NM_PARCELA DESC) LOOP
IF (j.CONTADOR = 1) THEN
EXTRA := EXTRA + 1;
UPDATE ZZ_PARCE_TEMP3
SET TEMP = EXTRA
WHERE NM_CONTRAT = i.NM_CONTRAT
AND NM_LIBERAC = i.NM_LIBERAC
AND CONTADOR = 1;
ELSE IF((j.CONTADOR = 0 OR j.CONTADOR = 2) OR ((EXTRA = 0) AND (j.CONTADOR = 1))) THEN
EXIT;
END IF;
END IF;
END LOOP;
END LOOP;
COMMIT;
END;
Consegui!!!
O que estava faltando era eu ordenar o primeiro e o segundo cursor no mesmo critério.
Para assim finalizar o somatório.
Muito Obrigado a todos que me ajudaram.