CONTAR REGISTROS

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

BOA TARDE PESSOAL,

BOM EU PRECISO DE UMA AJUDA DE VOCÊS.

EU UMA SEGUINTE PROCEDURE.

Selecionar tudo

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?
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

você tem certeza q essa condição é atendida?

Selecionar tudo

IF(V_CONTADOR = 1 ) THEN
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

Verifica duas coisas.

Se o cursor de fato traz registros e se no registro que ele traz o valor que é setado para a variavel v_contador é de fato 1.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

O CONTADOR É UM CRITÉRIO PARA UMA REGRA DE NEGÓCIO QUE TENHO.

Selecionar tudo

IF (NM_PARCE IN 'LIQ') AND  (DIAS PGTO < 15) THEN
CONTADOR := 1;
A TABLE FICARA ASSIM:

Selecionar tudo

CTR LIB PARCE SIT VL_BAI DIAS_PGTO CONT TEMP
1999003080; 001; 29; ABE; 274,76; -45; 1	
1999003080; 001; 28; LIQ; 5376,73; 0	
1999003080; 001; 27; LIQ; 5369,79; 14; 1	

DAE EU QUERO SETAR A COLUMN TEMP CONTANDO QUANTAS PARCELAS ESTÃO LIQ ATRAVÉS DA PRIMEIRA PARCELA COM CONTADOR 1. NISSO DENTRO DO MESMO CONTRATO.
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

O que este select traz??

Selecionar tudo

SELECT NM_CONTRAT,NM_LIBERAC,NM_PARCELA,CONTADOR,TEMP 
     FROM ZZ_PARCE;
posta o resultado dele aí.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

contrato, num da liberação, numero da parcela, o contador se é 1 ou 0, e a column temp em branco(campo temporário).
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

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.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

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á.
cttahara
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 12
Registrado em: Qui, 04 Mar 2010 4:28 pm
Localização: SP

Poderia ser feito dessa forma, sem utilizar cursor:

Selecionar tudo


  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;

EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

Bom eu utilizei esse seguinte código.

Selecionar tudo

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.
Diego_Mello
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 229
Registrado em: Sex, 05 Set 2008 2:59 pm
Localização: Igrejinha - RS
Diego Mello
Igrejinha - RS
www.twitter.com/diegolmello

Opa..

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.

Selecionar tudo

SELECT DISTINCT contador FROM zz_parce_temp;
SELECT DISTINCT nm_parcela FROM zz_parce_temp;
6º - Todo o teu código seria atendido por estes 2 updates básicos!!

Selecionar tudo

UPDATE zz_parce_temp
   SET temp = i.temp + temp
 WHERE i.contador = 1;

UPDATE zz_parce_temp
   SET temp = 0
 WHERE i.contador = 0
   AND i.nm_parcela >= 1;
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

tenta ai

Selecionar tudo

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.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

Bom meus caros...

Consegui evoluir na minha solução, mas ainda estou com alguns problemas.

Meu código semi-final é este

Selecionar tudo

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...
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

E te interessa pegar todas as liberações do contrato??

Se não tupo de colocar mais uma restrição no teu primeiro loop, de maneira que só teria um contrato, logo ao trocar de registro trocaria de contrato.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

no primeiro loop eu uso a liberação para fazer a validação com o segundo loop.

Cada liberação condiz a um produto. Então não posso retirar a liberação nesse caso.
EvertonKopec
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Ter, 29 Dez 2009 10:43 am
Localização: Curitiba
É isso aí...

Selecionar tudo

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.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 5 visitantes