修正oracle 發送帶附件郵件(smtp)無法打開,並增加報表改名發送

原文地址:https://blog.csdn.net/zhanzhib/article/details/42292455

經測試,好像單用戶發送沒問題附件沒問題,多用戶發送只有第一個用戶能正常打開附件。(PS格式,不完美)

2018/07/27 最終解決了多用戶發問題,原程序有幾個小問題,更新!

發郵件進程:

CREATE OR REPLACE Procedure NI_TEST_EMAIL(P_TXT Varchar2,
                                            P_SUB Varchar2,
                                            P_SENDOR Varchar2,
                                            P_RECEIVER Varchar2,
                                            P_SERVER Varchar2,
                                            P_PORT Number Default 25,
                                            P_NEED_SMTP Int Default 0,
                                            P_USER Varchar2 Default Null,
                                            P_PASS Varchar2 Default Null,
                                            P_FILENAME Varchar2 Default Null,
                                            P_ENCODE Varchar2 Default 'bit 7')
     Authid Current_User Is
     /*
     作用:用oracle發送郵件
     主要功能:1、支持多收件人。
               2、支持中文
               3、支持抄送人
               4、支持大於32K的附件
               5、支持多行正文
               6、支持多附件
               7、支持文本附件和二進制附件
               8、支持HTML格式

     參數說明:
               p_txt :郵件正文
               p_sub: 郵件標題
               p_SendorAddress : 發送人郵件地址
               p_ReceiverAddress : 接收地址,可以同時發送到多個地址上,地址之間用","或者";"隔開
               p_EmailServer : 郵件服務器地址,可以是域名或者IP
               p_Port :郵件服務器端口
               p_need_smtp:是否需要smtp認證,0表示不需要,1表示需要
               p_user:smtp驗證需要的用戶名
               p_pass:smtp驗證需要的密碼
               p_filename:附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。
                           可以有多個附件,附件名稱只見用逗號或者分號分隔
               p_encode:附件編碼轉換格式,其中 p_encode='bit 7' 表示文本類型附件
                                                p_encode='base64' 表示二進制類型附件

     注意:
           1、對於文本類型的附件,不能用base64的方式發送,否則出錯
           2、對於多個附件只能用同一種格式發送
     */
     L_CRLF Varchar2(2) := UTL_TCP.CRLF;
     L_SENDORADDRESS Varchar2(4000);
     L_SPLITE Varchar2(10) := '++';
     BOUNDARY Constant Varchar2(256) := '-----By ERP';
     FIRST_BOUNDARY Constant Varchar2(256) := '--' || BOUNDARY || L_CRLF;
     LAST_BOUNDARY Constant Varchar2(256) := '--' || BOUNDARY || '--' || L_CRLF;
		 --2018/07/27 增加charset=gb2312; 解決部分系統標題亂碼
     MULTIPART_MIME_TYPE Constant Varchar2(256) := 'multipart/mixed; charset=gb2312;boundary="' ||BOUNDARY || '"';
     /* 以下部分是發送大二進制附件時用到的變量 */
     L_FIL Bfile;
     L_FILE_LEN Number;
     --L_MODULO Number;
     L_PIECES Number;
     L_FILE_HANDLE UTL_FILE.FILE_TYPE;
		 --2018/07/27 屏蔽員 L_AMT:=672 * 3的賦值,是不能多用戶發送的元兇,再寫附件時初始化
     L_AMT Binary_Integer; /* ensures proper format;  2016 */ 
     L_FILEPOS Pls_Integer := 1; /* pointer for the file */
     --L_CHUNKS Number;
     L_BUF Raw(2100);
     L_DATA Raw(2100);
     --L_MAX_LINE_WIDTH Number := 54;
     L_DIRECTORY_BASE_NAME Varchar2(100) := 'DIR_FOR_SEND_MAIL';--此環境變量不存在的
     L_LINE Varchar2(1000);
     L_MESG Varchar2(32767);
     /* 以上部分是發送大二進制附件時用到的變量 */
     Type ADDRESS_LIST Is Table Of Varchar2(100) Index By Binary_Integer;
     MY_ADDRESS_LIST ADDRESS_LIST;
     Type ACCT_LIST Is Table Of Varchar2(100) Index By Binary_Integer;
     MY_ACCT_LIST ACCT_LIST;
     -------------------------------------返回附件源文件所在目錄或者名稱--------------------------------------
     Function GET_FILE(P_FILE Varchar2, P_GET Int) Return Varchar2 Is
          --p_get=1 表示返回目錄
          --p_get=2 表示返回文件名
          L_FILE Varchar2(1000);
     Begin
          If INSTR(P_FILE, '\') > 0 Then
               --windows
               If P_GET = 1 Then
                    L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '\', -1) - 1);
               Elsif P_GET = 2 Then
                    L_FILE := SUBSTR(P_FILE,
                                     - (LENGTH(P_FILE) -
                                       INSTR(P_FILE, '\', -1)));
               End If;
          Elsif INSTR(P_FILE, '/') > 0 Then
               --linux/unix
               If P_GET = 1 Then
                    L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '/', -1) - 1);
               Elsif P_GET = 2 Then
                    L_FILE := SUBSTR(P_FILE,
                                     - (LENGTH(P_FILE) -
                                       INSTR(P_FILE, '/', -1)));
               End If;
          End If;
          Return L_FILE;
     End;

     ---------------------------------------------刪除directory------------------------------------
     Procedure DROP_DIRECTORY(P_DIRECTORY_NAME Varchar2) Is
     Begin
          Execute Immediate 'drop directory ' || P_DIRECTORY_NAME;
     Exception
          When Others Then
               Null;
     End;

     --------------------------------------------------創建directory-----------------------------------------
     Procedure CREATE_DIRECTORY(P_DIRECTORY_NAME Varchar2, P_DIR Varchar2) Is
     Begin
          Execute Immediate 'create directory ' || P_DIRECTORY_NAME ||
                            ' as ''' || P_DIR || '''';
          Execute Immediate 'grant read,write on directory ' ||
                            P_DIRECTORY_NAME || ' to public';
     Exception
          When Others Then
               Raise;
     End;

     --------------------------------------------分割郵件地址或者附件地址-----------------------------------
     Procedure P_SPLITE_STR(P_STR Varchar2, P_SPLITE_FLAG Int Default 1) Is
          L_ADDR Varchar2(254) := '';
          L_LEN Int;
          L_STR Varchar2(4000);
          J Int := 0; --表示郵件地址或者附件的個數
     Begin
          /*處理接收郵件地址列表,包括去空格、將;轉換爲,等*/
          L_STR := Trim(RTRIM(Replace(Replace(P_STR, ';', ','), ' ', ''), ','));
          L_LEN := LENGTH(L_STR);
          For I In 1 .. L_LEN Loop
               If SUBSTR(L_STR, I, 1) <> ',' Then
                    L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1);
               Else
                    J := J + 1;
                    If P_SPLITE_FLAG = 1 Then
                         --表示處理郵件地址
                         --前後需要加上'<>',否則很多郵箱將不能發送郵件
                         L_ADDR := '<' || L_ADDR || '>';
                         --調用郵件發送過程
                         MY_ADDRESS_LIST(J) := L_ADDR;
                    Elsif P_SPLITE_FLAG = 2 Then
                         --表示處理附件名稱
                         MY_ACCT_LIST(J) := L_ADDR;
                    End If;
                    L_ADDR := '';
               End If;
               If I = L_LEN Then
                    J := J + 1;
                    If P_SPLITE_FLAG = 1 Then
                         --調用郵件發送過程
                         L_ADDR := '<' || L_ADDR || '>';
                         MY_ADDRESS_LIST(J) := L_ADDR;
                    Elsif P_SPLITE_FLAG = 2 Then
                         MY_ACCT_LIST(J) := L_ADDR;
                    End If;
               End If;
          End Loop;
     End;

     ------------------------------------------------寫郵件頭和郵件內容------------------------------------------
     Procedure WRITE_DATA(P_CONN In Out Nocopy UTL_SMTP.CONNECTION,
                          P_NAME In Varchar2,
                          P_VALUE In Varchar2,
                          P_SPLITE Varchar2 Default ':',
                          P_CRLF Varchar2 Default L_CRLF) Is
     Begin
          /* utl_raw.cast_to_raw 對解決中文亂碼問題很重要*/
          UTL_SMTP.WRITE_RAW_DATA(P_CONN,
                                  UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME ||
                                                              P_SPLITE ||
                                                              P_VALUE ||
                                                              P_CRLF,
                                                              'ZHS16GBK')));
     End;

     ----------------------------------------寫MIME郵件尾部-----------------------------------------------------
     Procedure END_BOUNDARY(CONN In Out Nocopy UTL_SMTP.CONNECTION,
                            Last In Boolean Default False) Is
     Begin
          UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
          If (Last) Then
               UTL_SMTP.WRITE_DATA(CONN, LAST_BOUNDARY);
          End If;
     End;

     ----------------------------------------------發送附件----------------------------------------------------
     Procedure ATTACHMENT(CONN In Out Nocopy UTL_SMTP.CONNECTION,
                          MIME_TYPE In Varchar2 Default 'text/plain',
                          INLINE In Boolean Default True,
                          FILENAME In Varchar2 Default 't.txt',
                          TRANSFER_ENC In Varchar2 Default '7 bit',
                          DT_NAME In Varchar2 Default '0') Is
          L_FILENAME Varchar2(1000);
     Begin
          --寫附件頭
          UTL_SMTP.WRITE_DATA(CONN, FIRST_BOUNDARY);
          --設置附件格式
          WRITE_DATA(CONN, 'Content-Type', MIME_TYPE);
          --如果文件名稱非空,表示有附件
          DROP_DIRECTORY(DT_NAME);
          --創建directory
          CREATE_DIRECTORY(DT_NAME, GET_FILE(FILENAME, 1));
          --得到附件文件名稱
          L_FILENAME := GET_FILE(FILENAME, 2);
          If (INLINE) Then
               WRITE_DATA(CONN,
                          'Content-Disposition',
                          'inline; filename="' || L_FILENAME || '"');
          Else
               WRITE_DATA(CONN,
                          'Content-Disposition',
                          'attachment; filename="' || L_FILENAME || '"');
          End If;
          --設置附件的轉換格式
          If (TRANSFER_ENC Is Not Null) Then
               WRITE_DATA(CONN, 'Content-Transfer-Encoding', TRANSFER_ENC);
          End If;
          UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
          --begin 貼附件內容
          If TRANSFER_ENC = 'bit 7' Then
               --如果是文本類型的附件
               Begin
                    L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME,
                                                    L_FILENAME,
                                                    'r'); --打開文件
                    --把附件分成多份,這樣可以發送超過32K的附件
                    Loop
                         UTL_FILE.GET_LINE(L_FILE_HANDLE, L_LINE);
                         L_MESG := L_LINE || L_CRLF;
                         WRITE_DATA(CONN, '', L_MESG, '', '');
                    End Loop;
                    UTL_FILE.FCLOSE(L_FILE_HANDLE);
                    END_BOUNDARY(CONN);
               Exception
                    When Others Then
                         UTL_FILE.FCLOSE(L_FILE_HANDLE);
                         END_BOUNDARY(CONN);
                         Null;
               End; --結束文本類型附件的處理
          Elsif TRANSFER_ENC = 'base64' Then
               --如果是二進制類型的附件
               Begin
                    L_AMT := 672 * 3;----2018/07/27 增加 初始化
                    --把附件分成多份,這樣可以發送超過32K的附件
                    L_FILEPOS := 1; --重置offset,在發送多個附件時,必須重置
                    L_FIL := BFILENAME(DT_NAME, L_FILENAME);
                    L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);
                    --L_MODULO := Mod(L_FILE_LEN, L_AMT);
                    L_PIECES := Ceil(L_FILE_LEN / L_AMT);--2018/07/26 附件打不開修改 TRUNC(L_FILE_LEN / L_AMT);
                   /* If (L_MODULO <> 0) Then
                         L_PIECES := L_PIECES + 1;
                    End If;*/
                    DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY);
                    DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
                    L_DATA := Null;
                    For I In 1 .. L_PIECES Loop
                         L_FILEPOS := I * L_AMT + 1;
                         L_FILE_LEN := L_FILE_LEN - L_AMT;
                         L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF);
                         /*L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) /L_MAX_LINE_WIDTH);
                         If (I <> L_PIECES) Then
                              L_CHUNKS := L_CHUNKS - 1;
                         End If;*/
                         UTL_SMTP.WRITE_RAW_DATA(CONN,UTL_ENCODE.BASE64_ENCODE(L_DATA));
                         L_DATA := Null;
                         If (L_FILE_LEN < L_AMT And L_FILE_LEN > 0) Then
                              L_AMT := L_FILE_LEN;
                         End If;
                         DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
                    End Loop;
                    DBMS_LOB.FILECLOSE(L_FIL);
                    END_BOUNDARY(CONN);
               Exception
                    When Others Then
                         DBMS_LOB.FILECLOSE(L_FIL);
                         END_BOUNDARY(CONN);
                         Raise;
               End; --結束處理二進制附件
          End If; --結束處理附件內容
          DROP_DIRECTORY(DT_NAME);
     End; --結束過程ATTACHMENT
     ---------------------------------------------真正發送郵件的過程--------------------------------------------
     Procedure P_EMAIL(P_SENDORADDRESS2 Varchar2, --發送地址
                       P_RECEIVERADDRESS2 Varchar2) --接受地址
      Is
          L_CONN UTL_SMTP.CONNECTION; --定義連接
     Begin
          /*初始化郵件服務器信息,連接郵件服務器*/
          L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER, P_PORT);
          --使用UTL_SMTP.HELO有可能會提示“ORA-29279: SMTP 永久性錯誤: 503 5.5.2 Send hello first.”
          --改成使用UTL_SMTP.EHLO就好了
          --UTL_SMTP.HELO(L_CONN, P_SERVER);
          UTL_SMTP.EHLO(L_CONN, P_SERVER);
          /* smtp服務器登錄校驗 */
          If P_NEED_SMTP = 1 Then
               UTL_SMTP.COMMAND(L_CONN, 'AUTH LOGIN', '');
               UTL_SMTP.COMMAND(L_CONN,
                                UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER))));
               UTL_SMTP.COMMAND(L_CONN,
                                UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS))));
          End If;
          /*設置發送地址和接收地址*/
          UTL_SMTP.MAIL(L_CONN, P_SENDORADDRESS2);
          UTL_SMTP.RCPT(L_CONN, P_RECEIVERADDRESS2);
          /*設置郵件頭*/
          UTL_SMTP.OPEN_DATA(L_CONN);
          --2018/07/26 WRITE_DATA(L_CONN,'Date',TO_CHAR(Sysdate, 'yyyy-mm-dd hh24:mi:ss'));
          /*設置發送人*/
          WRITE_DATA(L_CONN, 'From', P_SENDOR);
          /*設置接收人*/
          WRITE_DATA(L_CONN, 'To', P_RECEIVER);
          /*設置郵件主題*/
          WRITE_DATA(L_CONN, 'Subject', P_SUB);
          WRITE_DATA(L_CONN, 'Content-Type', MULTIPART_MIME_TYPE);
          UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
          UTL_SMTP.WRITE_DATA(L_CONN, FIRST_BOUNDARY);
          WRITE_DATA(L_CONN, 'Content-Type', 'text/plain;charset=gb2312');
          --單獨空一行,否則,正文內容不顯示
          UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
          /* 設置郵件正文
          把分隔符還原成chr(10)。這主要是爲了shell中調用該過程,如果有多行,則先把多行的內容合併成一行,並用 l_splite分隔
          然後用 l_crlf替換chr(10)。這一步是必須的,否則將不能發送郵件正文有多行的郵件
          */
          WRITE_DATA(L_CONN, '',Replace(Replace(P_TXT, L_SPLITE, CHR(10)),CHR(10),L_CRLF),'','');
          END_BOUNDARY(L_CONN);
          --如果文件名稱不爲空,則發送附件
          If (P_FILENAME Is Not Null) Then
               --根據逗號或者分號拆分附件地址
               P_SPLITE_STR(P_FILENAME, 2);
               --循環發送附件(在同一個郵件中)
               For K In 1 .. MY_ACCT_LIST.COUNT Loop
                    ATTACHMENT(CONN => L_CONN,
                               INLINE => false,
                               FILENAME => MY_ACCT_LIST(K),
                               TRANSFER_ENC => P_ENCODE,
                               DT_NAME => L_DIRECTORY_BASE_NAME ||TO_CHAR(K));
               End Loop;
          End If;
          /*關閉數據寫入*/
          UTL_SMTP.CLOSE_DATA(L_CONN);
          /*關閉連接*/
          UTL_SMTP.QUIT(L_CONN);
          /*異常處理*/
     Exception
          When Others Then
               Null;
               Raise;
     End;

     ---------------------------------------------------主過程-----------------------------------------------------
Begin
     L_SENDORADDRESS := '<' || P_SENDOR || '>';
     P_SPLITE_STR(P_RECEIVER); --處理郵件地址
     For K In 1 .. MY_ADDRESS_LIST.COUNT Loop
          P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K));
     End Loop;
     /*處理郵件地址,根據逗號分割郵件*/
Exception
     When Others Then
          Raise;
End;

報表附件發送前修改後綴,原報表後綴是.out,修改爲.ps(.xls也可以)

Declare
     p_Request_Id Number := 19779753;--報表ID
     v_email_address Varchar2(200) := '[email protected]';
     Cursor c Is
          Select a.Request_Id       Request_Id,
                 b.Outfile_Name     Outfile_Name,
                 a.Status_Code      Status_Code,
                 a.Phase_Code       Phase_Code,
                 b.Output_File_Type,
                 a.Program
            From Fnd_Conc_Req_Summary_v a, Fnd_Concurrent_Requests b
           Where a.Request_Id = b.Request_Id
                 And a.Request_Id = p_Request_Id
                 And a.Phase_Code = 'C'
                 And a.Status_Code = 'C'
                 And b.Outfile_Name Is Not Null;
   
     ln_last_split   Number;
     v_src_location  Varchar2(300);
     v_file_name     Varchar2(100);
     v_dest_filename Varchar2(100);
Begin
     For C1 In c Loop
          ln_last_split := instr(C1.Outfile_Name, '/', -1, 1);
          --原名
          v_file_name := substr(C1.Outfile_Name, ln_last_split + 1);
          --轉名後(改ps後綴)
          v_dest_filename := substr(v_file_name,1,instr(v_file_name, '.', -1, 1) ) ||'ps';
          --最終文件路徑
          v_src_location := substr(C1.Outfile_Name, 1, ln_last_split) || v_dest_filename;
          utl_file.fcopy('REPORT_DIR', --(需手動創建)環境變量路徑 create directory REPORT_DIR as 路徑地址; 
                         v_file_name, --原文件名
                         'REPORT_DIR', --(需手動創建)環境變量路徑 create directory REPORT_DIR as 路徑地址;
                         v_dest_filename --拷貝後文件名
                         );
          NI_TEST_EMAIL(C1.program || 'output file',
                        C1.program,
                        '[email protected]',
                        v_email_address,
                        'smtp1.email.com',
                        25,
                        0,
                        Null,
                        Null,
                        v_src_location,
                        'base64');
     End Loop;
End;

(此問題已解決,保留當其他方式)同時發給多個EMAIL用戶,附件有打不開的情況,分拆成單個發送又沒問題。

分拆方法,下文中出現ni_app_ext.split()代碼:

--先創建數組
CREATE OR REPLACE TYPE NI_STR_ARRAY is VARRAY(10000) OF VARCHAR2(500)
--分拆函數
Function Split(v_source Varchar2, v_delimiter Varchar2 Default ',')
     Return NI_STR_ARRAY Is
     l_DelLen Number;
     l_Pos    Number;
     l_Start  Number;
     l_Length Number;
     l_holder Varchar2(200);
     l_Array NI_STR_ARRAY := ni_str_array();
Begin
     --Check for NULL
     If v_source Is Null
        Or v_delimiter Is Null Then
          l_Array.Extend;
          l_Array(l_Array.Count) := '';
          Return l_Array;
     End If;
     --Get the length of the delimeter
     l_DelLen := Length(v_Delimiter);
     l_Pos := instr(Upper(v_source), Upper(v_Delimiter));
     --Only one entry was found
     If l_Pos = 0 Then
          l_Array.extend;
          l_Array(l_Array.Count) := v_source;
          Return l_Array;
     End If;
     --More than one entry was found - loop to get all of them
     l_Start := 1;
     While l_Pos > 0 Loop
          --Set current entry
          l_Length := l_Pos - l_Start;
          l_holder := substr(v_source, l_start, l_length);
          -- Update array and counter
          l_Array.extend;
          l_Array(l_Array.Count) := l_holder;
          --Set the new starting position
          l_Start := l_Pos + l_DelLen;
          l_Pos := instr(Upper(v_source), Upper(v_Delimiter), l_Start);
     End Loop;
     --Set last entry
     l_holder := substr(v_source, l_start, Length(v_source));
     -- Update array and counter if necessary
     If Length(l_holder) > 0 Then
          l_Array.extend;
          l_Array(l_Array.Count) := l_holder;
     End If;
     --Return the number of entries found
     Return l_Array;
End;

循環分拆發送:

Declare
     p_Request_Id Number := 19781729;
     v_email_address Varchar2(1000) := '[email protected];[email protected];[email protected]';
     Cursor c Is
          Select a.Request_Id       Request_Id,
                 b.Outfile_Name     Outfile_Name,
                 a.Status_Code      Status_Code,
                 a.Phase_Code       Phase_Code,
                 b.Output_File_Type,
                 a.Program
            From Fnd_Conc_Req_Summary_v a, Fnd_Concurrent_Requests b
           Where a.Request_Id = b.Request_Id
                 And a.Request_Id = p_Request_Id
                 And a.Phase_Code = 'C'
                 And a.Status_Code = 'C'
                 And b.Outfile_Name Is Not Null;
     
     ln_last_split   Number;
     v_src_location  Varchar2(300);
     v_file_name     Varchar2(100);
     v_dest_filename Varchar2(100);
     v_one_email Varchar2(100);
Begin
     For C1 In c Loop
          ln_last_split := instr(C1.Outfile_Name, '/', -1, 1);
          --原名
          v_file_name := substr(C1.Outfile_Name, ln_last_split + 1);
          --轉名後(改ps後綴)
          v_dest_filename := substr(v_file_name,1,instr(v_file_name, '.', -1, 1) ) ||'xls';
          --最終文件路徑
          v_src_location := substr(C1.Outfile_Name, 1, ln_last_split) || v_dest_filename;
          utl_file.fcopy('REPORT_DIR', --環境變量路徑 DIRECTORY_NAME
                         v_file_name, --原文件名
                         'REPORT_DIR', --環境變量路徑 DIRECTORY_NAME
                         v_dest_filename --拷貝後文件名
                         );
          --循環發郵件開始
          For i In 1 .. ni_app_ext.split(v_email_address,';').count Loop
            v_one_email:=null;
            v_one_email:=ni_app_ext.split(v_email_address, ';') (i);
            If v_one_email Is Not Null Then
              NI_TEST_EMAIL(C1.program || '附件!'||chr(10)||'如出現無法打開現象,請自行到ERP中獲取,報表ID:'||p_Request_Id,
                            C1.program,
                            '[email protected]',
                            v_one_email,
                            'smtp1.email.com',
                            25,
                            0,
                            Null,
                            Null,
                            v_src_location,
                            'base64');
             End If;
          End Loop;              
          --循環發郵件結束
     End Loop;
End;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章