본문 바로가기

업무/DB

[ORACLE] SMTP 메일 보내기 - 메일 하나에 다건(리스트) 보내기

메일 보내는 프로시져를 만든 후

DB JOB에 스케쥴을 추가하여 자동으로 메일을 발송하게 함.

(매일 아침 정기배치 확인에 유용)

create or replace PROCEDURE SEND_MAIL   
(
    ad_date             IN    DATE,
    av_ret_code         OUT   VARCHAR2,
    av_ret_message      OUT   VARCHAR2
) IS
    g_smtphost          VARCHAR2(100) := 'smtp주소';
    g_connection utl_smtp.connection;

    v_header            VARCHAR2(1000);
    v_message           VARCHAR2(32767);

    v_receiver_nm       VARCHAR2(100);
    v_receiver_addr     VARCHAR2(100);
    
    v_sender_nm         VARCHAR2(100);
    v_sender_addr       VARCHAR2(100);
    
    v_mail_message      VARCHAR2(32767);
    v_mail_title        VARCHAR2(500) := '메일 제목';
BEGIN
    av_ret_code     := 'SUCCESS!';
    av_ret_message  := 'PROC START';

    -- -----------------------------------------------
    --  수신자, 발신자의 메일 정보
    -- -----------------------------------------------
    v_receiver_nm := null;
    v_receiver_addr := null;

    v_sender_nm := null;
    v_sender_addr := null;
    
    v_mail_message := null;
    
    -- -----------------------------------------------
    --  메일 내용
    -- -----------------------------------------------
    -- 상단 제목
      v_mail_message := '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
      v_mail_message := v_mail_message || '<html>';
      v_mail_message := v_mail_message || '<head>';
      v_mail_message := v_mail_message || '<title>SEND MAIL</title>';
      v_mail_message := v_mail_message || '<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">';
      v_mail_message := v_mail_message || '</head>';
      v_mail_message := v_mail_message || '<body>';   
      v_mail_message := v_mail_message || '<div>';
      v_mail_message := v_mail_message || '<table style="width: 1000px; border-collapse: collapse; height: 50px;" border="1">';
      v_mail_message := v_mail_message || '<thead style="background:#BDBDBD">';
      v_mail_message := v_mail_message || '<tr>';
      v_mail_message := v_mail_message || '<th> 컬럼1 </th>';
      v_mail_message := v_mail_message || '<th> 컬럼2 </th>';
      v_mail_message := v_mail_message || '<th> 컬럼3 </th>';
      v_mail_message := v_mail_message || '<th> 컬럼4 </th>';
      v_mail_message := v_mail_message || '<th> 컬럼5 </th>';
      v_mail_message := v_mail_message || '</tr>';
      v_mail_message := v_mail_message || '</thead>';
      v_mail_message := v_mail_message || '<tbody>';
      
    -- 내용
    BEGIN
    
    FOR CUST_LIST IN (
        SELECT '<tr>' ||
                            '<td>' ||  컬럼1  || '</td>' || 
                            '<td>' ||  컬럼2  || '</td>' || 
                            '<td>' ||  컬럼3  || '</td>' || 
                            '<td>' ||  컬럼4  || '</td>' || 
                            '<td>' ||  컬럼5  || '</td>' || 
               '</tr>' AS DATA
           FROM DUAL;
    ) LOOP 
    
        v_mail_message := v_mail_message || CUST_LIST.DATA;
        
    END LOOP;
    
    v_mail_message := v_mail_message || '</tbody>';
    v_mail_message := v_mail_message || '</table>';
    v_mail_message := v_mail_message || '</div>';
    v_mail_message := v_mail_message || '</body>';
    v_mail_message := v_mail_message || '</html>';

    END;

    -- -----------------------------------------------
    --  메일 보내기
    -- -----------------------------------------------
    BEGIN
        --SMTP server을 이용하여 connection
        g_connection := utl_smtp.open_connection(g_smtphost, '포트번호');

        --SMTP server와 UTL_SMTP.HELO() call을 통해 초기화
        utl_smtp.helo(g_connection, g_smtphost);
        
        -- 보내는사람 정보
        v_sender_nm    := '보내는사람 이름'
        v_sender_addr  := '보내는사람 메일'
        
        -- 받는사람 정보
        v_receiver_nm   := '받는사람 이름';
        v_receiver_addr := '받는사람 메일';

        -- 보내는사람
        utl_smtp.mail(g_connection, v_sender_addr);
        
        -- 받는사람
        utl_smtp.rcpt(g_connection, v_receiver_addr);
         
        v_header := 'MIME-Version: 1.0' || CHR(13) || CHR(10);
        v_header := '';
        v_header :=  v_header || 'To : ';

        -- Cc로 넣었더니 메일 수신이 안되어 To로 변경함
        v_header :=  v_header || '"' || v_receiver_nm || '" <' || v_receiver_addr || '>'; -- 받는 사람이 여러명인 경우 , 로 붙이면 가능
        v_header :=  v_header || CHR(13) || CHR(10);
        
        --DBMS_OUTPUT.PUT_LINE(v_header);
        v_header :=  v_header || 'From :' || v_sender_nm || ' <' || v_sender_addr || '>'  || CHR(13) || CHR(10);
        v_header :=  v_header || 'Subject :' || v_mail_title || CHR(13) || CHR(10);
        v_header :=  v_header || 'Reply-To :' || v_sender_addr || CHR(13) || CHR(10);
        v_header :=  v_header || 'content-type:text/html;charset=euc-kr' || CHR(13) || CHR(10) || CHR(13) || CHR(10);

        v_message := v_header || v_mail_message ;

        utl_smtp.open_data(g_connection);
        utl_smtp.write_raw_data(g_connection, UTL_RAW.CAST_TO_RAW(v_message));
        utl_smtp.close_data(g_connection);

        utl_smtp.quit(g_connection);

    EXCEPTION
        WHEN OTHERS THEN
            av_ret_code    := 'FAILURE!';
            av_ret_message := 'ERROR';
            utl_smtp.quit(g_connection);
            ROLLBACK ;
            RETURN ;
    END;

    IF AV_RET_CODE = 'SUCCESS!' THEN
            AV_RET_MESSAGE := 'SUCCESS';
    END IF;
        
  av_ret_code    := 'SUCCESS!';
  av_ret_message := 'PROC END';
END;