Skip to content
Advertisement

Group By function

hope you all having a great day. I need some help with this query. Just to explain the situation, I have to send e-mails containing the data found in this select, but I have to group by customers (TBLOTE.CEMPRES) so it would build a single e-mail for each customer found. Example, if the query finds 3+ row for customer ´John Inc.´ and 1 row for ´Jack Corp.´, it should send 2 e-mails, one containing the 3+ rows about John Inc, and the other one containing the 1 row found for Jack Corp. I hope I could be clear enough on my explanation.

create or replace PROCEDURE PR_ENVIA_EMAIL_LOTE_ESTOQUE IS


V_REMETENTE     VARCHAR2(50) := 'servidor@oracle.com.br';
V_SAUDACAO      VARCHAR2(50);
V_ASSUNTO       VARCHAR2(200);
V_ASSINATURA    VARCHAR2(100);
V_MENSAGEM      VARCHAR2(6000);
V_COD_ERRO      NUMBER(2);
V_MSG_ERRO      VARCHAR2(1);
TDESCRI_ARMAZEM VARCHAR2(50);
TDESCRI         VARCHAR2(60);

BEGIN 

    FOR C1 IN (SELECT TBPJUR.TDESCRI  EMPRESA,
                      TBLOTE.CEMPRES  COD_EMPRESA,
                      TBLOTE.NNOTFIS  NOTA_FISCAL, 
                      TBLOTE.CLOTE    LOTE, 
                      TBARMAZ.TDESCRI ARMAZEM,  
                      TBNOTF.DDTFATU  DATA_FAT_NF,  
                      TBLOTE.DRECEBTO DATA_RECEBTO, 
                      TBLOTE.CPRODUT  COD_PRODUTO, 
                      TBPRODU.TDESCRI PRODUTO,
                      TBLOTAR.QQTESTQ QTD_ESTOQUE,
                      Decode(TBLOTE.F_ARMAZENAGEM, 'S', 'SIM', 'N', 'NÃO') ARMAZENAGEM,
                      Decode(TBLOTE.SLTENCR, 'S', 'SIM', 'N', 'NÃO')  ENCERRADO,
                      TO_DATE(Sysdate, 'dd/mm/yyyy') - TO_DATE(TBLOTE.DRECEBTO, 'dd/mm/yyyy')DIAS_EM_ESTOQUE
                 FROM TBLOTE,
                      TBLOTAR,
                      TBPRODU,
                      TBARMAZ,
                      TBNOTF
                WHERE TBLOTE.CPRODUT       = TBPRODU.CPRODUT
                  AND TBLOTE.CLOTE         = TBLOTAR.CLOTE
                  AND TBLOTAR.CARMAZE      = TBARMAZ.CARMAZE
                  AND TBLOTE.NNOTFIS       = TBNOTF.NNOTFIS
                  AND TBLOTE.CEMPRES       = TBNOTF.CEMPRES
                  AND TBLOTE.CEMPRES       = TBPJUR.CEMPRES
                  AND TBLOTE.SLTENCR       = 'N'
                  AND TBLOTE.F_ARMAZENAGEM = 'S'
                  AND TBLOTE.NNOTFIS IS NOT NULL 
                  AND TO_DATE(Sysdate, 'dd/mm/yyyy') - TO_DATE(TBLOTE.DRECEBTO, 'dd/mm/yyyy') >= 165
                  ORDER BY DIAS_EM_ESTOQUE DESC)
       LOOP
    DBMS_OUTPUT.PUT_LINE('LENDO '||C1.NOTA_FISCAL|| ' - ' ||C1.LOTE|| ' - ' ||C1.ARMAZEM|| ' - ' ||C1.PRODUTO|| ' - Dias em Estoque: ' || C1.DIAS_EM_ESTOQUE);

   BEGIN
      IF TO_NUMBER(TO_CHAR(SYSDATE,'HH24')) < 12 THEN
         V_SAUDACAO:= 'Bom Dia!';
      ELSIF TO_NUMBER(TO_CHAR(SYSDATE,'HH24')) >= 12 AND
            TO_NUMBER(TO_CHAR(SYSDATE,'HH24'))    <  18 THEN
            V_SAUDACAO:= 'Boa tarde!';
      ELSE
         V_SAUDACAO:= 'Boa noite!';
      END IF;
        
        
        V_ASSUNTO := 'AVISO: Lotes em estoque.';

        V_MENSAGEM := ' Os seguintes lotes ja estao há pelo menos 165 dias em nosso estoque, favor verificar: '||CHR(10)||CHR(10);

      V_MENSAGEM := V_MENSAGEM ||'Nota Fiscal : '||C1.NOTA_FISCAL||CHR(10)||
                                 'Lote : '||C1.LOTE||CHR(10)||
                                 'Armazem : '||C1.ARMAZEM||CHR(10)||
                                 'Dt. Faturamento : '||To_Date(C1.DATA_FAT_NF, 'DD/MM/YYYY')||CHR(10)||
                                 'Dt. Recebimento : '||C1.DATA_RECEBTO||CHR(10)||
                                 'Produto : '||C1.PRODUTO||CHR(10)||CHR(10)|| 
                                 'Qtd. em Estoque : '||C1.QTD_ESTOQUE||CHR(10)||
                                 'Dias em Estoque : '||C1.DIAS_EM_ESTOQUE||CHR(10)||CHR(10)||
                                 'Estamos a disposiçao.'||CHR(10)||CHR(10)||CHR(10)||
                                 'Att. '||CHR(10)||CHR(10)||
                                 'Departamento de T.I'||CHR(10)||
                                 '---';

      V_MENSAGEM := V_SAUDACAO||CHR(10)||CHR(10)||
                    V_MENSAGEM||
                    CHR(10)||CHR(10)||CHR(10)||CHR(10)||
                    V_ASSINATURA;
                                                    

       FOR C2 IN (SELECT EMAIL_USUARIO
                        FROM   TBEMAIL_INTERNO
                        WHERE  F_LOTE_ESTOQUE = 'S'
                        AND    F_EXCLUSAO_LOGICA   = 'N')
              LOOP
              
            
                PR_ENVIA_EMAIL(V_REMETENTE,
                               C2.EMAIL_USUARIO,
                               V_ASSUNTO,
                               V_MENSAGEM,
                               V_COD_ERRO,
                               V_MSG_ERRO);
                                                            
       END LOOP;                                   

    END;
 
 END LOOP ;           
    

      EXCEPTION
         WHEN OTHERS THEN
            dbms_output.put_line('ATENÇÃO: ERRO AO CHAMAR ROTINA PR_ENVIA_EMAIL_LOTE_ESTOQUE: '||SQLERRM);


END PR_ENVIA_EMAIL_LOTE_ESTOQUE;

Advertisement

Answer

Currently you have 2 loops. The outer loop (cursor C1) loops through all records and the inner loop (cursor c2) loops through the email addresses and sends an email for every iteration. This can be written in pseudo code as:

LOOP through all records
  LOOP through email addresses and send mail

To satisfy your requirement, add a 3rd loop:

LOOP through distinct customers
  LOOP through all records for current customer
    LOOP through email addresses and send email
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement