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
12 horas atrás, Motta disse:

Dadosadv é um owner ?

Se o dado deve existir na Z46 pq inserir ?

 

 

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

Eu faria +ou- assim

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 felipeaggs
      Boa-tarde, pessoal!
       
      Estou com um problema e não consigo resolvê-lo de forma alguma.
       
      Vou exemplificar aqui o que acontece.
       
      Tenho duas tabelas, uma tabela é relativa a registro de nota fiscal, estruturada da seguinte forma (edição simplificada).
       
      TGFCAB
      ID | DTNEG        | NUMNOTA | CODTIPOPER | CODEMP | 
      1 | 01/01/2019 | 1000            | 50                     | 7              |
      2 | 02/01/2019 | 1001            | 50                     | 7              |
      3 | 02/01/2019 | 1002            | 50                     | 7              |
      4 | 03/01/2019 | 1003            | 50                     | 7              |
       
      TGFITE
      ID | NUMNOTA | QTDNEG| VLRUNIT | VLRTOT | CODVOL | PRODUTONFE 
      1   |1001            | 5              | 10            | 50            | UN           | 10
      2   |1001            | 10            | 700          | 7000        | TN           | 11
      3   |1002            | 3              | 20            |60            | UN           | 12
      4   |1003            | 20            | 7              | 140          | UN           | 10
      5   |1003            | 100          | 7              | 700          | UN           | 10
       
       
      Eu preciso realizar um select de forma que traga as Informação abaixo.
       
      PRODUTO| QTDNEGMES | VALORTOTAL 
      10             | 125           | 890
      11             | 10             | 7000
      12             | 3               | 60
       
      Já tentei de todas as formas possíveis, porém eu não consigo de forma alguma.
       
      Por favor, alguém poderia me ajudar?
       
       
       
       
    • By asacap1000
      Galera estou com uma consulta que travei em uma situação.
      Eu preciso buscar as ultimas informações de uma Nota fiscal.
       
      NUMERO DA NF | DATA FATURAMENTO | COBERTURA
       
      neste select ele utiliza como parâmetro o lote cadastrado no sistema de estoque, e ao pesquisar ele volta a Data do faturamento e cobertura corretos porém o numero da NF é outro bem antiga.
      O que posso estar fazendo errado nesta consulta?? segue a query 
      SELECT TO_CHAR(MAX(OS.NR_NF)) NOTA, TO_CHAR(MAX(TO_DATE(REPLACE(OS.DATE_BILL, '/.', ''), 'dd/mm/yy')), 'dd/mm/yyyy') DATA_FAT, TO_CHAR(MAX(TO_DATE(REPLACE(IT.DIV_6, '/.', ''), 'dd/mm/yy')), 'dd/mm/yyyy') COBERTURA FROM BILL_OS_ITEM IT, BILL_OS OS, BILL_ITEM B WHERE OS.LAGER = IT.LAGER AND OS.ID_KLIENT = IT.ID_KLIENT AND OS.ID_OS = IT.ID_OS AND IT.LAGER = OS.LAGER AND IT.ID_OS = OS.ID_OS AND IT.BILLITE = B.BILLITE AND OS.STATUS <> '80' --AND OS.NR_NF = '119247' AND IT.DIV_1 = 'EX16208816' A nota fiscal que deveria retornar ´seria a 119247, porém vem  99336.
    • By RAFAEL C D EMELO
      Bom dia amigos,
       
      me deparei com um problema estou criando uma procedure que precisa criar uma PK em uma tabela ja existente e apos isso realizar um insert porem quando existe um dado duplicado por algum motive a exception DUP_VAL_ON_INDEX NAO FUNCIONA  o insert funcionou mas quando testo uma situacao de duplicacao eu recebo um erro oracle 02260 e diz que a tabela somente pode ter uma PK porem a exception deveria tartar o erro ,
      eu vou deixar o codigo a baixo par se alguem puder me ajudar isso
      desde ja agradeco a todos,
       
      CREATE OR REPLACE PROCEDURE MANUAL_CLIENT_INSERT_FIP AS
      Y_CONT NUMBER := 0;
      W_CONT NUMBER;
          BEGIN 
           
           EXECUTE IMMEDIATE 'ALTER TABLE TEMP_FIP_CLIENT_HISTORIC
                              ADD PRIMARY KEY (CLIENTKEY)';
           
              FOR REG IN (SELECT LOADDATE,
                          CLIENTKEY,
                          CLIENTSEGMENT,
                          CLIENTNAME,
                          'UK' AS COUNTRY,
                          'FIP' AS PROGRAM,
                          'TPL' AS COVERAGE
              FROM TEMP_FIP_CLIENT_HISTORIC
      )
       LOOP
       
        BEGIN
          W_CONT := NVL(W_CONT, 0)+ 1;
                
           DBMS_OUTPUT.PUT_LINE('RECORDS' ||'-'|| W_CONT ||' '||REG.LOADDATE||' '||REG.CLIENTKEY||' '||REG.CLIENTSEGMENT||' '|| REG.CLIENTNAME||' '||'UK'||' '||'FIP'||' '||'TPL');
                                                
            INSERT INTO GV_MANUAL_CLIENT(LOADDATE, CLIENTKEY,  CLIENTSEGMENT,   CLIENTNAME,  COUNTRY,  PROGRAM,  COVERAGE )
            VALUES                      (SYSDATE,  REG.CLIENTKEY, REG.CLIENTSEGMENT, REG.CLIENTNAME, REG.COUNTRY, REG.PROGRAM, REG.COVERAGE);
         
         
         EXCEPTION
               WHEN DUP_VAL_ON_INDEX THEN
               DBMS_OUTPUT.PUT_LINE(W_CONT ||'  '||'DUPLICATE KEY');  
          END; 
         
       END LOOP;
      END;
    • By matlaureto
      Pessoal, boa tarde!!!
      Gostaria de uma opinião de vocês... sempre trabalhei no Oracle utilizando left join, inner join, e não a marcação de join especifica da oracle (+).
      Quando estudei para a certificação 1Z0-047, OCE SQL Expert, lá mesmo falava para não utilizar a marcação (+) por se tratar de um código depreciado.
      Alguem sabe informar se essa marcação realmente é depreciada? Estou trabalhando em uma empresa onde o padrão dos joins é com esta marcação da Oracle, então to buscando informações sobre isso.
      Alguem sabe me orientar quanto a isso?
      Muito obrigado a todos!!
×

Important Information

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