Jump to content
Abran

PL SQL (Select dentro do LOOP)

Recommended Posts

Gostaria de poder fazer um SELECT dentro do LOOP igual ao exemplo abaixo.
Esse exemplo não deu certo, se tirar esse SELECT que está dentro do LOOP, tudo funciona. O problema está no Select dentro do LOOP que nao aceita.

ORA-01403: dados não encontrados

 

A ideia é, Z45 grava cliente, e Z46 grava títulos em aberto.

Toda vez que rodar, deverá checar se existe novos títulos que ainda não foram gravados, e só gravar os que ainda não foram.

 

Alguem sabe alguma maneira de fazer o que preciso ?

 

DECLARE
  
  v_CODCLI   VARCHAR2 (6);
  vPREFIXO   VARCHAR2 (3);
  vNUM       VARCHAR2 (9);
  vPARCELA   VARCHAR2 (3);
BEGIN
    
    v_CODCLI := '0';
    
    FOR V_FUNC IN
    (
    SELECT E1_FILIAL, A1_COD, A1_LOJA, A1_PESSOA, E1_PREFIXO, E1_NUM, E1_PARCELA, E1_TIPO, E1_NATUREZ, E1_EMISSAO, E1_VENCREA, E1_VALOR,
    CASE WHEN TO_DATE('20190627', 'yyyymmdd') - TO_DATE(E1_VENCTO, 'yyyymmdd') < 0         
    THEN 0   
    ELSE TO_DATE('20190627', 'yyyymmdd') - TO_DATE(E1_VENCTO, 'yyyymmdd') END ATRASO 
    FROM SE1010 SE1 
    INNER JOIN SA1010 A1 ON A1.A1_COD = E1_CLIENTE AND A1_LOJA = E1_LOJA AND A1.D_E_L_E_T_ = SE1.D_E_L_E_T_ 
    WHERE SE1.D_E_L_E_T_ = ' ' 
    ORDER BY A1_LOJA, A1_COD
    )
    LOOP    
    
        SELECT Z46_PREFIX, Z46_NUM, Z46_PARCEL, Z46_TIPO, Z46_NATURE 
        INTO vPREFIXO, vNUM, vPARCELA, vTIPO, vNATUREZ 
        FROM Z46010 Z46 
        WHERE Z46_PREFIX = V_FUNC.E1_PREFIXO
        AND Z46_NUM = V_FUNC.E1_NUM 
        AND Z46_PARCEL = V_FUNC.E1_PARCELA
        AND D_E_L_E_T_ = ' ' ;
                
        IF vPREFIXO || vNUM || vPARCELA !=  V_FUNC.E1_PREFIXO || V_FUNC.E1_NUM || V_FUNC.E1_PARCELA THEN
        
            IF V_FUNC.A1_COD <> v_CODCLI THEN
            
                v_CODCLI :=  V_FUNC.A1_COD;
                
                INSERT
                INTO DADOSADV.Z45010
                (
                    Z45_RECNO,
                    Z45_FILIAL,
                    Z45_CODCLI,
                    Z45_LOJA,
                    Z45_PESSOA,
                    Z45_DTCAD
                )
                VALUES
                (
                    (SELECT CASE WHEN MAX(Z45_RECNO) IS NULL THEN 1 ELSE MAX(Z45_RECNO) + 1 END Z45_RECNO FROM Z45010) ,
                    V_FUNC.E1_FILIAL,
                    V_FUNC.A1_COD,
                    V_FUNC.A1_LOJA,
                    V_FUNC.A1_PESSOA,
                    TO_CHAR(SYSDATE, 'YYYYMMDD')
                );
                
                COMMIT;
            
            END IF;
            
            INSERT
            INTO DADOSADV.Z46010
            (
                    Z46_RECNO,
                    Z46_RECZ45,
                    Z46_STATIT,
                    Z46_PREFIX,
                    Z46_NUM,
                    Z46_PARCEL,
                    Z46_TIPO,
                    Z46_NATURE,
                    Z46_VALOR,
                    Z46_ATRASO,
                    Z46_DTCAD
            )
            VALUES
            (
                (SELECT CASE WHEN MAX(Z46_RECNO) IS NULL THEN 1 ELSE MAX(Z46_RECNO) + 1 END Z46_RECNO FROM Z46010) ,
                (SELECT CASE WHEN MAX(Z45_RECNO) IS NULL THEN 1 ELSE MAX(Z45_RECNO) END Z45_RECNO FROM Z45010),
                0,
                V_FUNC.E1_PREFIXO,
                V_FUNC.E1_NUM,
                V_FUNC.E1_PARCELA,
                V_FUNC.E1_TIPO,
                V_FUNC.E1_NATUREZ,
                20,
                V_FUNC.ATRASO,
                TO_CHAR(SYSDATE, 'YYYYMMDD')
            );
            
            COMMIT;            
        
        END IF;
    
    END LOOP;
         
END;

Share this post


Link to post
Share on other sites

Dadosadv é um owner ?

Se o dado deve existir na Z46 pq inserir ?

 

Share this post


Link to post
Share on other sites

Dadosadv é um owner ?
Sim


A ideia é, Z45 grava cliente, e Z46 grava títulos em aberto.

Toda vez que rodar, deverá checar se existe novos títulos que ainda não foram gravados, e só gravar os que ainda não foram.

Share this post


Link to post
Share on other sites

Tente trocar esta parte do bloco

LOOP    
        BEGIN
            SELECT Z46_PREFIX, Z46_NUM, Z46_PARCEL, Z46_TIPO, Z46_NATURE
            INTO vPREFIXO, vNUM, vPARCELA, vTIPO, vNATUREZ
            FROM Z46010 Z46
            WHERE Z46_PREFIX = V_FUNC.E1_PREFIXO
            AND Z46_NUM = V_FUNC.E1_NUM
            AND Z46_PARCEL = V_FUNC.E1_PARCELA
        EXCEPTION
          WHEN OTHERS THEN
            vPREFIXO:= NULL;
            vNUM:= NULL;
            vPARCELA:= NULL;
            vTIPO:= NULL;
            vNATUREZ:= NULL;
        END;        
        
        
        AND D_E_L_E_T_ = ' ' ;
                
        IF vPREFIXO || vNUM || vPARCELA !=  V_FUNC.E1_PREFIXO || V_FUNC.E1_NUM || V_FUNC.E1_PARCELA IS NULL THEN


       

Protheus em Oracle ...

raro

Share this post


Link to post
Share on other sites

Nessas tabelas eu gravo os Títulos de cobrança que estão em aberto para gerar carta de cobrança.
Cada titulo de cobrança ao ser gravado terá um STATUS, dependendo da quantidade de dias de atraso.
Se o titulo de cobrança mudar de faixa, ele será inserido novamente com STATUS diferente.
Por isso preciso que todos os títulos sejam verificados.
E tem uma parte que vou criar ainda que irá fazer as verificações de mudança de status.

A intenção dessas tabelas é registrar as emissões de carta de cobrança e ter um histórico da movimentação de status.

 

Eu não conhecia o EXCEPTION WHEN. Funcionou agora certinho. Só não sei dizer se realmente essa seria a melhor logica, mas vou estudar aqui. Obrigado!!!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By asacap1000
      Salve galera. estou com uma zica aqui e não vai.
      Tenho um servidor WEB final IP final 120 neste servidor eu acesso um banco de dados de outro servidor 122, tem uma tabela com fotos e precisaria mostrar estas fotos na intranet. porém ele me mostra o caminho mas não mostra a imagem.
       
      Na Tabela está sendo salvo desta forma:
      Z:/Avarias/FOTOS/Alfandegado/2020/01.%20JANEIRO/14.01.2020/AVARIA%20CLIENTE%20CN=%20191234%20(2).JPG
       
      Chamei ele na tela desta forma:
      <?php ociexecute($stmt2,OCI_DEFAULT); while ($row = oci_fetch_object($stmt2)) { $string = OCIResult ($stmt2 ,1); ///link da avaria $avaria = OCIResult ($stmt2 ,2); ///titulo da avaria ?> <a href="<?=$string ?>" width="20%" height="30%" data-lightbox="gallery" > <button type="button" class="btn btn-dark active" data-toggle="modal" data-target="#modalExemplo"> <img src="<?=$string?>" width="160" height="100" class="rounded" title="<?=$avaria?>"> <br> </button> Na tela aparece desta forma:

       
      Se eu clicar na imagem fica assim apenas carregando:
       

       
      Se eu mandar abrir em nova guia a imagem aparece essa mensagem:

      Se eu copiar o link com botão direito e abrir no navegador ela abre normalmente.
       
      Ah lembrando que são tres servidores 120 web, 122 banco de dados, 128 as fotos onde salva como mapeamento Z://
      Alguem teria alguma idéia de como chamar estas fotos???
       
    • By Motta
      Google e Oracle decidem na Suprema Corte briga judicial sobre Android
    • By Motta
      Oracle lança programa educacional para capacitar jovens na área de TI
    • By Maccio
      Estou tentando criar um relatório com total de horas trabalhadas do funcionários por dia, tenho uma tabela FRQ_digitacao onde eu tenho os dados para calcular o total de horas e se tiver com zero horas eu digo a ocorrência do mesmo, ex: falta, Folga, etc. Quero também colocar a informação de férias quando o mesmo estiver de férias, porém quando ele está de férias a tabela FRQ_digitacao fica sem registros nos dias de Férias, assim tenho que buscar a informação na tabela FLP_Ferias onde é lá que diz o gozoinicial e gozofinal, porém não estou conseguindo fazer essa comparação já que na tabela FRQ_digitacao nesses dias de ferias o funcionário fica sem registro.
       
      select T.CODINTFUNC, f.CHAPAFUNC, LISTAGG( CASE WHEN T.NORMALDIGIT=0 THEN OC.DESCMAPAOCORR WHEN t.DTDIGIT IS NULL THEN 'dt.dtdigit' --when dt.dtdigit between fe.inicio and fe.fim --then 'FER' ELSE to_char((TRUNC(T.NORMALDIGIT)+TRUNC(t.extradigit)+TRUNC(t.extranotdigit))+ ((trunc(((T.NORMALDIGIT-trunc(T.NORMALDIGIT))+(t.extradigit-trunc(t.extradigit))+(t.extranotdigit-trunc(t.extranotdigit)))/0.60))+ mod(((T.NORMALDIGIT - trunc(T.NORMALDIGIT))+(t.extradigit - trunc(t.extradigit))+(t.extranotdigit - trunc(t.extranotdigit))),0.60)),'FM99999D90', 'nls_numeric_characters=''.,''' ) END, ' ') within group (order by t.dtdigit) horas, MAX(FE.INICIO), MAX(FE.FIM ) from vw_funcionarios f, FRQ_DIGITACAOMOVIMENTO O, FRQ_OCORRENCIA OC, frq_digitacao t, (select f.codintfunc INT, f.chapafunc, max(fe.dtcompetfer)COMPET, MAX(fe.gozoinifer) INICIO, MAX(fe.Gozofinfer) FIM from flp_ferias fe, flp_funcionarios f where f.codintfunc=fe.codintfunc AND F.SITUACAOFUNC='A' and f.codigoempresa=1 AND FE.STATUSFERIAS='N' group by f.chapafunc, f.codintfunc) FE, (select t.DTDIGIT from frq_digitacao t WHERE t.dtdigit between '01-NOV-2019' AND '20-NOV-2019' group by t.dtdigit) DT where DT.DTDIGIT(+)=T.dtdigit and fe.INT=t.codintfunc and f.codintfunc=t.codintfunc AND F.CODIGOEMPRESA=1 and O.CODINTFUNC=T.CODINTFUNC AND T.DTDIGIT=O.DTDIGIT AND O.CODOCORR=OC.CODOCORR AND dt.dtdigit BETWEEN '01-NOV-2019' AND '20-NOV-2019' -- AND F.CODDEPTO BETWEEN 15 AND 15 AND O.STATUSDIGIT='N' and o.iddigit = (select max(p.iddigit) from frq_digitacaomovimento p where o.codintfunc=p.codintfunc and o.dtdigit=p.dtdigit AND P.STATUSDIGIT='N' and p.dtdigit between '01-NOV-2019' AND '20-NOV-2019') group by f.CHAPAFUNC, T.CODINTFUNC  



    • By ronimarcos.silva
      Estou com a seguinte situação: No Mysql eu consegui fazer em  "insert into" de uma única vez, com vários registros, conforme abaixo:
      insert into prefeitos (nome, cidade_id) VALUES ('Rodrigo Neves', 2), ('Caique Rosa Baldran', 9), ('Raquel Lira', 11), ('Maísa Albuquerque Sain', 12), ('Zenaldo Coutinho', null); Porém, no Oracle 12C, usando a mesma forma que no Mysql, está dando o seguinte erro: 
      insert into e080rat (CODEMP, CODSER, SEQRAT, TIPRSC, CRIRAT, NUMPRJ, CODFPJ, CTAFIN, CTARED, PERCTA, CODCCU, PERRAT) values ('800', 'S0001', '279', 'U', '5', '0', '0', '1360', '13730', '100', '31058', '100'), ('800', 'S0001', '280', 'U', '5', '0', '0', '1360', '13730', '100', '31060', '100'), ('800', 'S0001', '281', 'U', '5', '0', '0', '1360', '13730', '100', '31202', '100'), ('800', 'S0001', '282', 'U', '5', '0', '0', '1360', '13730', '100', '31203', '100'); ORA-00933: comando SQL não encerrado adequadamente
      Será que a sintaxe no Oracle é diferente?
       
      Eu sei que assim funciona perfeitamente:
      insert into e080rat (CODEMP, CODSER, SEQRAT, TIPRSC, CRIRAT, NUMPRJ, CODFPJ, CTAFIN, CTARED, PERCTA, CODCCU, PERRAT) values ('800', 'S0001', '279', 'U', '5', '0', '0', '1360', '13730', '100', '31058', '100'); insert into e080rat (CODEMP, CODSER, SEQRAT, TIPRSC, CRIRAT, NUMPRJ, CODFPJ, CTAFIN, CTARED, PERCTA, CODCCU, PERRAT) values ('800', 'S0001', '280', 'U', '5', '0', '0', '1360', '13730', '100', '31060', '100'); insert into e080rat (CODEMP, CODSER, SEQRAT, TIPRSC, CRIRAT, NUMPRJ, CODFPJ, CTAFIN, CTARED, PERCTA, CODCCU, PERRAT) values ('800', 'S0001', '281', 'U', '5', '0', '0', '1360', '13730', '100', '31202', '100'); insert into e080rat (CODEMP, CODSER, SEQRAT, TIPRSC, CRIRAT, NUMPRJ, CODFPJ, CTAFIN, CTARED, PERCTA, CODCCU, PERRAT) values ('800', 'S0001', '282', 'U', '5', '0', '0', '1360', '13730', '100', '31203', '100');  
      Porém, eu tenho uma tabela com quase 100.000 registros e gostaria de fazer em um único "insert". Eu uso o PL/SQLDeveloper e quando faço o "insert" da forma acima, com vários "insert into", ele abre um novo documento para cada "insert into", nisso ele trava, fica horas rodando o "insert" e não conclui se for em um único "insert" como no Mysql, creio que não pesaria tanto.
      Tem uma forma mais fácil de fazer o "insert into" com muitos dados envolvidos?
      Desde já agradeço.
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.