将SQL查询输出作为CSV附件发送(pl / sql)

时间:2018-01-22 10:15:36

标签: oracle

我有一个pl / sql查询,我希望它的输出能够通过电子邮件以CSV格式直接发送。我没有目录可以先创建并保存CSV文件,然后将其选中以作为附件发送。

请帮助您输入,因为我无法逃脱。

此致 萨钦

2 个答案:

答案 0 :(得分:1)

最后在收到指针的帮助下找到了一个解决方案,并提供了相同的帮助以防万一其他人将来需要。

我的问题是我主要看到的例子,我可以将文件保存在目录上,或从目录中选择文件作为附件发送,但我没有提供目录,我希望查询结果放在以CSV格式并动态发送电子邮件。所以这是完整的解决方案。

CREATE OR REPLACE PROCEDURE  SEND_CSV_ATTACHMENT AS
    v_sender                        VARCHAR2(130);
    v_recipients                    VARCHAR2(4000);
    v_cc                            VARCHAR2(4000);
    v_bcc                           VARCHAR2(2000);
    v_subj                          VARCHAR2(200);
    v_msg                           CLOB;
    v_mime                          VARCHAR2(40);
    v_tbl                             VARCHAR2(20000);
    c_cr_lf                       CONSTANT CHAR (2) := (CHR (13) || CHR (10)); -- Carriage Return/Line Feed characters for formatting text emails
    v_loop_count            PLS_INTEGER := 0;
    v_attachment            CLOB;


      v_block_qry VARCHAR2(3000); 
      v_block_row VARCHAR2(6000); 
    TYPE bl_cur IS REF CURSOR;
    v_result bl_cur;
    v_rowcount NUMBER;
    errMsg      VARCHAR2(15000);   

  BEGIN

      v_sender := 'mmxlcr@tatacommunications.com';      

      SELECT NVL(EMAIL_LIST, 'someone@abcd.com')   
      FROM
      (
        SELECT LISTAGG(EMAIL_ID, ',') WITHIN GROUP (ORDER BY EMAIL_ID) AS EMAIL_LIST FROM RECIPEINTS_TABLE WHERE SEND_TO = 1 AND IS_ACTIVE = 1
      );     

      SELECT NVL(EMAIL_LIST, 'someone@abcd.com')   
      FROM
      (
        SELECT LISTAGG(EMAIL_ID, ',') WITHIN GROUP (ORDER BY EMAIL_ID) AS EMAIL_LIST FROM RECIPEINTS_TABLE WHERE SEND_CC = 1 AND IS_ACTIVE = 1
      );    


      v_bcc := 'someone@abcd.com';

      -- Generate attachment - Begin 
      v_attachment := '"COL1", "COL2"' || CHR(13) || CHR(10);


      v_block_qry := 'SELECT ''"'' || COL1 || ''", "'' || COL2 ||  ''"'' AS ROWTXT        
                      FROM MY_TABLE';


      OPEN v_result FOR v_block_qry;
        LOOP 
        v_rowcount := v_result%ROWCOUNT;
        FETCH v_result INTO v_block_row;
          EXIT WHEN v_result%NOTFOUND;          
          v_attachment := v_attachment || v_block_row || chr(13) || chr(10);
        END LOOP;
      CLOSE v_result;

      -- Generate attachment - End



    v_subj:= 'MAIL_SUBJECT ' || TO_CHAR(TRUNC(SYSDATE-1), 'YYYY-MM-DD');

      UTL_MAIL.send_attach_varchar2(sender => v_sender,
      recipients        => v_recipients,
      cc                => v_cc,
      bcc               => v_bcc,
      subject           => v_subj,
      message           =>  v_msg,
      mime_type         => 'text/html; charset=us-ascii', -- send html e-mail
      attachment        => v_attachment, 
      att_inline        => FALSE,
      att_filename      => 'Change_Report' || TO_CHAR(TRUNC(SYSDATE-1), 'YYYY-MM-DD') || '.csv');
  EXCEPTION    
    WHEN OTHERS THEN
    errMsg := SQLERRM;    
    SEND_MAIL_HTML ('someone@abcd.com', NULL, NULL, errMsg, 'SEND_MAIL ERROR: ' || errMsg);   

END SEND_CSV_ATTACHMENT;

答案 1 :(得分:0)

您可以创建这样的程序:

create or replace procedure prFileSend is
  v_mail_owner varchar2(100):='myname@someComp.com';
  v_url        varchar2(4000);
  v_rep        varchar2(4000);
  delimiter    varchar2(1) := chr(38);
begin
   for c in ( select * from myTable ) 
   loop
   begin
         v_url := 'http://www.mycompany.com/einfo/default.aspx?email='||c.email || delimiter || 'p1=' || c.col1 || delimiter ||'p2='||c.col2;
         v_rep := utl_http.request(utl_url.escape(v_url, false,'ISO-8859-9'));
    end;
    end loop;
exception
  when others then
    prErrorMsgSend(v_mail_owner,'Error : ' || sqlerrm); -- a function like this one which sends an error message back to you.   
end;

并创建一个调度程序作业

begin
dbms_scheduler.create_job (
   job_name           =>  'jbFileSend ',
   job_type           =>  'STORED_PROCEDURE',
   job_action         =>  'prFileSend',
   start_date         =>  '22-jan-2018 09:00:00 am',
   repeat_interval    =>  'FREQ=DAILY; INTERVAL=1',
   comments           =>  'Sending Every day'
   enabled            =>   true);
end;

每天工作为例。