PROCEDURE SEND_MAIL(P_SUBJECT VARCHAR2, --信件標題
P_RCPT VARCHAR2, --收件者 以分號區分
P_CC VARCHAR2 DEFAULT NULL, --副本 以分號區分
P_MSG CLOB, --郵件內容
P_MSG_CLOB CLOB, --附件內容
P_FILENAME VARCHAR2, --附件名稱
P_HTML VARCHAR2 DEFAULT 'Y') IS
MAIL_CONN UTL_SMTP.CONNECTION;
V_USERNAME VARCHAR2(200) := UTL_ENCODE.TEXT_ENCODE('mailuser@XXXX.com.tw',
'WE8ISO8859P1',
UTL_ENCODE.BASE64);
V_PASSWORD VARCHAR2(200) := UTL_ENCODE.TEXT_ENCODE('mail@@XXXX',
'WE8ISO8859P1',
UTL_ENCODE.BASE64);
V_MAIL_SERVER VARCHAR2(200) := 'smtp.office365.com';
V_MAILER VARCHAR2(200) := 'mailuser@XXXX.com.tw';
V_RCPT VARCHAR2(4000) := REPLACE(REPLACE(P_RCPT, ' ', ''),' ','');
V_CC VARCHAR2(4000) := REPLACE(REPLACE(P_CC, ' ', ''),' ','');
V_CRLF VARCHAR2(2) := CHR(13) || CHR(10);
V_IS_GROUP NUMBER := 0;
V_IS_GROUP_CC NUMBER := 0;
V_RCPT_CNT NUMBER := 0;
V_CC_CNT NUMBER := 0;
V_RCPT_MAIL VARCHAR2(2000);
V_CC_MAIL VARCHAR2(2000);
V_REPLY UTL_SMTP.REPLY;
L_STEP PLS_INTEGER := 12000; -- make sure you set a multiple of 3 not higher than 24573
BEGIN
--開啟 Mail Connection 物件
MAIL_CONN := UTL_SMTP.OPEN_CONNECTION(HOST => V_MAIL_SERVER,
PORT => 25,
--TX_TIMEOUT => 100,
WALLET_PATH => 'file:/u01/wallets/office365', --'file:/u1/PROD/wallets/office365',
WALLET_PASSWORD => 'XXXX',
SECURE_CONNECTION_BEFORE_SMTP => FALSE);
--建立連線
UTL_SMTP.EHLO(MAIL_CONN, V_MAIL_SERVER); --DO NOT USE HELO
V_REPLY := UTL_SMTP.STARTTLS(MAIL_CONN);
UTL_SMTP.EHLO(MAIL_CONN, V_MAIL_SERVER); --DO NOT USE HELO
UTL_SMTP.COMMAND(MAIL_CONN, 'AUTH LOGIN');
UTL_SMTP.COMMAND(MAIL_CONN, V_USERNAME);
UTL_SMTP.COMMAND(MAIL_CONN, V_PASSWORD);
--設定寄件者
UTL_SMTP.MAIL(MAIL_CONN, V_MAILER);
--設定收件者
V_IS_GROUP := INSTR(V_RCPT, ',');
IF V_IS_GROUP > 0 THEN
--多筆收件者
LOOP
SELECT INSTR(V_RCPT, ',') INTO V_RCPT_CNT FROM DUAL;
IF V_RCPT_CNT != 0 THEN
V_RCPT_MAIL := SUBSTR(V_RCPT, 1, V_RCPT_CNT - 1);
UTL_SMTP.RCPT(MAIL_CONN, V_RCPT_MAIL);
ELSE
UTL_SMTP.RCPT(MAIL_CONN, V_RCPT);
EXIT;
END IF;
V_RCPT := SUBSTR(V_RCPT, V_RCPT_CNT + 1);
END LOOP;
ELSE
--單筆收件者
UTL_SMTP.RCPT(MAIL_CONN, P_RCPT);
END IF;
--設定副本
V_IS_GROUP_CC := INSTR(V_CC, ',');
IF NVL(V_IS_GROUP_CC, 0) > 0 THEN
--多筆收件者
LOOP
SELECT INSTR(V_CC, ',') INTO V_CC_CNT FROM DUAL;
IF V_CC_CNT != 0 THEN
V_CC_MAIL := SUBSTR(V_CC, 1, V_CC_CNT - 1);
UTL_SMTP.RCPT(MAIL_CONN, V_CC_MAIL);
ELSE
UTL_SMTP.RCPT(MAIL_CONN, V_CC);
EXIT;
END IF;
V_CC := SUBSTR(V_CC, V_CC_CNT + 1);
END LOOP;
ELSE
--單筆收件者
IF P_CC IS NOT NULL THEN
UTL_SMTP.RCPT(MAIL_CONN, P_CC);
END IF;
END IF;
--設定發信內容
UTL_SMTP.OPEN_DATA(MAIL_CONN);
--寫入發信標題
--UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('DATE: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('FROM: ' || V_MAILER || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('TO: ' || P_RCPT || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CC: ' || P_CC || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('SUBJECT: ' || P_SUBJECT || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('MIME-VERSION: 1.0' || V_CRLF));
--Add v1.02
IF P_FILENAME IS NOT NULL THEN
--有附件
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TYPE: MULTIPART/MIXED; BOUNDARY="SECBOUND"' || V_CRLF || V_CRLF));
ELSE
--無附件
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TYPE: MULTIPART/ALTERNATIVE; BOUNDARY="SECBOUND"' || V_CRLF || V_CRLF));
END IF;
--設定發信內容
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('--SECBOUND' || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TYPE: TEXT/HTML; ' || V_CRLF || V_CRLF));
--UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TYPE: TEXT/PLAIN; ' || V_CRLF || V_CRLF));--等待擴充
--UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN, UTL_RAW.CAST_TO_RAW(P_MSG));
FOR I IN 0 .. TRUNC((DBMS_LOB.GETLENGTH(P_MSG) - 1) / L_STEP) LOOP
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(P_MSG,L_STEP,I * L_STEP + 1)));
END LOOP;
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('--SECBOUND' || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('--SECBOUND' || V_CRLF));
IF P_FILENAME IS NOT NULL THEN
--設定附件
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TYPE: TEXT/CSV; NAME="' || P_FILENAME || '.CSV"' ||V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-TRANSFER-ENCODING: 8BIT' || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('CONTENT-DISPOSITION: ATTACHMENT;' || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW('FILENAME="' || P_FILENAME || '.CSV"' || V_CRLF));
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN, UTL_RAW.CAST_TO_RAW(V_CRLF));
FOR I IN 0 .. TRUNC((DBMS_LOB.GETLENGTH(P_MSG_CLOB) - 1) / L_STEP) LOOP
UTL_SMTP.WRITE_RAW_DATA(MAIL_CONN,UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(P_MSG_CLOB,L_STEP,I * L_STEP + 1)));
END LOOP;
END IF;
--關閉發信內容
UTL_SMTP.CLOSE_DATA(MAIL_CONN);
--結束連線
UTL_SMTP.QUIT(MAIL_CONN);
DBMS_OUTPUT.PUT_LINE('郵件發送成功');
EXCEPTION
WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
DBMS_OUTPUT.PUT_LINE('郵件發送失敗');
UTL_SMTP.QUIT(MAIL_CONN);
DBMS_OUTPUT.PUT_LINE(SQLCODE || SQLERRM);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || SQLERRM);
END;
2022-12-28
[Oracle]發送郵件,並突破VARCHAR2字元上限
需要搭配BLOB to CLOB轉換
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言