[英]Unable to send attachment through PL/SQL for multiple lines inside attachment using UTL_SMTP
有人可以帮助我使用 UTL_SMTP.WRITE_DATA 发送带附件的 email。 我无法发送包含多行代码的附件。
当我编写 UTL_SMTP.WRITE_DATA 以在附件中写入数据时,它不起作用。
下面是附加代码,当 i=1 时,它仅从第二个 cursor 发送 1 行的附件。
有人请帮忙。
CREATE OR REPLACE PACKAGE BODY xx_common_alerts_pkg AS
gv_process_name CONSTANT VARCHAR2(100) := 'Common Alert Functionality';
PROCEDURE main (
po_errbuf OUT VARCHAR2,
po_retcode OUT NUMBER,
-- p_debug IN NUMBER,
p_alert_name IN VARCHAR2
) IS
lv_procedure CONSTANT VARCHAR2(200) := 'XX_COMMON_ALERTS_PKG.main';
lv_to_recipients alr_actions.to_recipients%TYPE;
lv_cc_recipients alr_actions.cc_recipients%TYPE;
lv_bcc_recipients alr_actions.bcc_recipients%TYPE;
lv_subject alr_actions.subject%TYPE;
lv_alert_id alr_alerts.alert_id%TYPE;
lv_row_count alr_action_set_checks.row_count%TYPE;
lv_check_id alr_action_set_checks.alert_check_id%TYPE;
v_clob CLOB := empty_clob();
v_clob_lines CLOB := empty_clob();
lv_mail_body_lines VARCHAR2(30000);
lv_ctxh dbms_xmlgen.ctxhandle;
lv_queryresult XMLTYPE;
lv_xslt_transform XMLTYPE;
lv_message VARCHAR2(30000);
lv_error_msg VARCHAR2(3000);
lv_inst_name VARCHAR2(50);
lv_from_email VARCHAR2(100);
lv_to_email VARCHAR2(100);
lv_recipients_mail VARCHAR2(100);
lv_status VARCHAR2(30000);
lv_alert_check_id VARCHAR2(2000);
lv_list_id alr_actions.list_id%TYPE;
lv_list_application_id alr_actions.list_application_id%TYPE;
lv_body alr_actions.body%TYPE;
lv_ret_message VARCHAR2(2000);
lv_ret_status VARCHAR2(2000);
lv_attach_tab t_attach_tab := t_attach_tab();
v_from VARCHAR2(80) := 'abc@gmail.com';
v_recipient VARCHAR2(80) := 'def@gmail.com';
v_subject VARCHAR2(80) := 'test';
v_mail_host VARCHAR2(80) := 'mlocalhost'; --localhost';
v_smtp_port NUMBER := 25;
v_mail_conn utl_smtp.connection;
l_step PLS_INTEGER := 12000;
crlf VARCHAR2(2) := chr(13)
|| chr(10);
v_len INTEGER;
v_index INTEGER := 1;
le_mail_excp EXCEPTION;
CURSOR c_get_alert_outputs (
pi_alert_id VARCHAR2
) IS
SELECT
name,
title
FROM
alr_alert_outputs
WHERE
alert_id = pi_alert_id
AND end_date_active IS NULL
ORDER BY
name DESC;
CURSOR c_output_lines (
pi_check_id NUMBER,
pi_row_number NUMBER
) IS
SELECT DISTINCT
value,
name
FROM
alr_output_history
WHERE
check_id = pi_check_id
AND row_number = pi_row_number
ORDER BY
name DESC;
BEGIN
SELECT
actions.to_recipients,
actions.cc_recipients,
actions.bcc_recipients,
actions.subject,
alr.alert_id,
actions.list_id,
actions.list_application_id,
actions.body
INTO
lv_to_recipients,
lv_cc_recipients,
lv_bcc_recipients,
lv_subject,
lv_alert_id,
lv_list_id,
lv_list_application_id,
lv_body
FROM
alr_alerts alr,
alr_actions actions
WHERE
alr.alert_name = p_alert_name
AND alr.alert_id = actions.alert_id
AND actions.name = 'Send Email'
AND actions.enabled_flag = 'Y'
AND actions.end_date_active IS NULL;
IF lv_list_id IS NOT NULL THEN
SELECT
to_recipients,
cc_recipients,
bcc_recipients
INTO
lv_to_recipients,
lv_cc_recipients,
lv_bcc_recipients
FROM
alr_distribution_lists
WHERE
list_id = lv_list_id
AND application_id = lv_list_application_id
AND enabled_flag = 'Y'
AND end_date_active IS NULL;
END IF;
SELECT
row_count,
check_id,
alert_check_id
INTO
lv_row_count,
lv_check_id,
lv_alert_check_id
FROM
alr_action_set_checks
WHERE
alert_id = lv_alert_id
AND alert_check_id = (
SELECT
MAX(alert_check_id)
FROM
alr_action_set_checks
WHERE
alert_id = lv_alert_id
);
-- lv_attach_tab.DELETE;
v_mail_conn := utl_smtp.open_connection(v_mail_host, 25);
utl_smtp.helo(v_mail_conn, v_mail_host);
utl_smtp.mail(v_mail_conn, v_from);
utl_smtp.rcpt(v_mail_conn, v_recipient);
FOR rec_alert_outputs IN c_get_alert_outputs(lv_alert_id) LOOP
v_clob := rec_alert_outputs.title
|| ','
|| v_clob;
END LOOP;
FOR i IN 1..lv_row_count LOOP
v_clob_lines := empty_clob();
FOR rec_lines IN c_output_lines(lv_check_id, i) LOOP
v_clob_lines := rec_lines.value
|| ','
|| v_clob_lines;
END LOOP;
utl_smtp.data(v_mail_conn, 'Date: '
|| TO_CHAR(SYSDATE, 'Dy, DD Mon YYYY hh24:mi:ss')
|| crlf
|| 'From: '
|| v_from
|| crlf
|| 'Subject: '
|| v_subject
|| crlf
|| 'To: '
|| v_recipient
|| crlf
|| 'MIME-Version: 1.0'
|| crlf
|| -- Use MIME mail standard
'Content-Type: multipart/mixed;'
|| crlf
|| ' boundary="-----SECBOUND"'
|| crlf
|| crlf
|| '-------SECBOUND'
|| crlf
|| 'Content-Type: text/plain;'
|| crlf
|| 'Content-Transfer_Encoding: 7bit'
|| crlf
|| crlf
|| lv_body
|| crlf
|| crlf
|| '-------SECBOUND'
|| crlf
|| 'Content-Type: text/plain;'
|| crlf
|| ' name="ASL_Mismatch.csv"'
|| crlf
|| 'Content-Transfer_Encoding: 8bit'
|| crlf
|| 'Content-Disposition: attachment;'
|| crlf
|| ' filename="Mismatch.csv"'
|| crlf
|| crlf
|| v_clob
|| crlf
|| v_clob_lines
|| crlf);
fnd_file.put_line(fnd_file.output, 'v_clob ' || v_clob);
utl_smtp.data(v_mail_conn, v_clob);
utl_smtp.data(v_mail_conn, v_clob_lines);
--UTL_SMTP.write_data(v_Mail_Conn, UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(v_clob_lines, 1, i * 1))) || UTL_TCP.crlf);
--UTL_SMTP.write_data(v_Mail_Conn,UTL_RAW.cast_to_varchar2(v_clob_lines));
-- utl_smtp.write_data(v_Mail_Conn, v_clob_lines);
-- UTL_SMTP.write_data(v_Mail_Conn, DBMS_LOB.SUBSTR(v_clob_lines, 32000, v_index));
fnd_file.put_line(fnd_file.output, 'v_clob_lines '
|| v_clob_lines
|| ' Row: '
|| i);
END LOOP;
utl_smtp.write_data(v_mail_conn, utl_tcp.crlf);
utl_smtp.write_data(v_mail_conn, '--'
|| ' boundary="-----SECBOUND"'
|| '--'
|| utl_tcp.crlf);
utl_smtp.close_data(v_mail_conn);
utl_smtp.quit(v_mail_conn);
EXCEPTION
WHEN OTHERS THEN
lv_error_msg := p_alert_name
|| '-'
|| lv_status
|| ': '
|| sqlerrm;
--debug(pi_message => lv_error_msg
-- );
END main;
END xx_common_alerts_pkg;
我不会尝试调试您的代码,而是与您分享我自己的 sendmail function,您可以使用它来找出您做错了什么。 我立即注意到的一个区别是我使用 base64 编码而不是 8 位编码,以防止附件中的任何内容弄乱 SMTP。我确信有多种方法可以做到这一点,但这一直适用于多年的我:
CREATE OR REPLACE PROCEDURE sendmail_html(sender_email IN varchar2,
recipient_email IN varchar2,
message_in IN clob,
subject_in IN varchar2 := NULL,
sender_name IN varchar2 :=NULL,
recipient_name IN varchar2 := NULL,
attachment_name_1 IN varchar2 := NULL,
attachment_mime_1 IN varchar2 := NULL,
attachment_clob_1 IN clob := NULL,
attachment_name_2 IN varchar2 := NULL,
attachment_mime_2 IN varchar2 := NULL,
attachment_clob_2 IN clob := NULL,
attachment_name_3 IN varchar2 := NULL,
attachment_mime_3 IN varchar2 := NULL,
attachment_clob_3 IN clob := NULL,
attachment_name_4 IN varchar2 := NULL,
attachment_mime_4 IN varchar2 := NULL,
attachment_clob_4 IN clob := NULL,
attachment_name_5 IN varchar2 := NULL,
attachment_mime_5 IN varchar2 := NULL,
attachment_clob_5 IN clob := NULL)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
mail_host varchar2(30) := 'localhost';
mail_connection utl_smtp.connection;
message clob;
message_piece varchar2(2000);
boundary VARCHAR2(50) := '----=*#abc1234321cba#*=';
step PLS_INTEGER := 12000; -- make sure you set a multiple of 3 not higher than 24573
var_start_pos integer;
var_unencoded_raw raw(32767);
var_encoded_raw raw(32767);
var_encoded_string varchar2(32767);
BEGIN
message := message_in;
mail_connection := utl_smtp.open_connection(mail_host, 25);
utl_smtp.helo(mail_connection, mail_host);
utl_smtp.mail(mail_connection, sender_email);
utl_smtp.rcpt(mail_connection, recipient_email);
utl_smtp.open_data(mail_connection);
utl_smtp.write_data(mail_connection,'Date: '||TO_CHAR(SYSDATE,'dd Mon yy hh24:mi:ss')||utl_tcp.CRLF);
utl_smtp.write_data(mail_connection,'From: '||NVL(sender_name,sender_email)||' <'||sender_email||'>'||utl_tcp.CRLF);
utl_smtp.write_data(mail_connection,'To: '||NVL(recipient_name,recipient_email)||' <'||recipient_email||'>'||utl_tcp.CRLF);
utl_smtp.write_data(mail_connection,'Subject: '||NVL(subject_in,' ')|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'MIME-Version: 1.0' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: multipart/mixed; boundary="' || boundary || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
IF dbms_lob.getlength(message) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: text/html; charset=us-ascii ' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: inline' || utl_tcp.CRLF || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '<html>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '<head>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '<title>'||NVL(subject_in,' ')||'</title>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '</head>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '<body>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '<pre style="font: monospace">'|| utl_tcp.CRLF);
FOR chunk IN 1..CEIL(dbms_lob.getlength(message)/1000)
LOOP
var_start_pos := 1+(chunk-1)*1000;
utl_smtp.write_data(mail_connection,dbms_lob.substr(message,1000,var_start_pos));
END LOOP;
utl_smtp.write_data(mail_connection, '</pre>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '</body>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '</html>'|| utl_tcp.CRLF);
utl_smtp.write_data(mail_connection,utl_tcp.CRLF||utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: text/plain; charset="iso-8859-1"; format=flowed' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: inline' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR chunk IN 1..CEIL(dbms_lob.getlength(message)/1000)
LOOP
var_start_pos := 1+(chunk-1)*1000;
utl_smtp.write_data(mail_connection,dbms_lob.substr(message,1000,var_start_pos));
END LOOP;
utl_smtp.write_data(mail_connection,utl_tcp.CRLF||utl_tcp.CRLF);
END IF;
IF LENGTH(attachment_clob_1) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: ' || attachment_mime_1 || '; name="' || attachment_name_1 || '"' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: attachment; filename="' || attachment_name_1 || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR i IN 0 .. TRUNC((dbms_lob.getlength(attachment_clob_1) - 1 )/step)
LOOP
var_unencoded_raw := utl_raw.cast_to_raw(dbms_lob.substr(attachment_clob_1, step, i * step + 1));
var_encoded_raw := utl_encode.base64_encode(var_unencoded_raw);
var_encoded_string := utl_raw.cast_to_varchar2(var_encoded_raw);
utl_smtp.write_data(mail_connection, var_encoded_string);
END LOOP;
utl_smtp.write_data(mail_connection, utl_tcp.CRLF || utl_tcp.CRLF);
END IF;
IF LENGTH(attachment_clob_2) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: ' || attachment_mime_2 || '; name="' || attachment_name_2 || '"' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: attachment; filename="' || attachment_name_2 || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR i IN 0 .. TRUNC((dbms_lob.getlength(attachment_clob_2) - 1 )/step)
LOOP
var_unencoded_raw := utl_raw.cast_to_raw(dbms_lob.substr(attachment_clob_2, step, i * step + 1));
var_encoded_raw := utl_encode.base64_encode(var_unencoded_raw);
var_encoded_string := utl_raw.cast_to_varchar2(var_encoded_raw);
utl_smtp.write_data(mail_connection, var_encoded_string);
END LOOP;
utl_smtp.write_data(mail_connection, utl_tcp.CRLF || utl_tcp.CRLF);
END IF;
IF LENGTH(attachment_clob_3) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: ' || attachment_mime_3 || '; name="' || attachment_name_3 || '"' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: attachment; filename="' || attachment_name_3 || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR i IN 0 .. TRUNC((dbms_lob.getlength(attachment_clob_3) - 1 )/step)
LOOP
var_unencoded_raw := utl_raw.cast_to_raw(dbms_lob.substr(attachment_clob_3, step, i * step + 1));
var_encoded_raw := utl_encode.base64_encode(var_unencoded_raw);
var_encoded_string := utl_raw.cast_to_varchar2(var_encoded_raw);
utl_smtp.write_data(mail_connection, var_encoded_string);
END LOOP;
utl_smtp.write_data(mail_connection, utl_tcp.CRLF || utl_tcp.CRLF);
END IF;
IF LENGTH(attachment_clob_4) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: ' || attachment_mime_4 || '; name="' || attachment_name_4 || '"' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: attachment; filename="' || attachment_name_4 || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR i IN 0 .. TRUNC((dbms_lob.getlength(attachment_clob_4) - 1 )/step)
LOOP
var_unencoded_raw := utl_raw.cast_to_raw(dbms_lob.substr(attachment_clob_4, step, i * step + 1));
var_encoded_raw := utl_encode.base64_encode(var_unencoded_raw);
var_encoded_string := utl_raw.cast_to_varchar2(var_encoded_raw);
utl_smtp.write_data(mail_connection, var_encoded_string);
END LOOP;
utl_smtp.write_data(mail_connection, utl_tcp.CRLF || utl_tcp.CRLF);
END IF;
IF LENGTH(attachment_clob_5) > 0
THEN
utl_smtp.write_data(mail_connection, '--' || boundary || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Type: ' || attachment_mime_5 || '; name="' || attachment_name_5 || '"' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.CRLF);
utl_smtp.write_data(mail_connection, 'Content-Disposition: attachment; filename="' || attachment_name_5 || '"' || utl_tcp.CRLF || utl_tcp.CRLF);
FOR i IN 0 .. TRUNC((dbms_lob.getlength(attachment_clob_5) - 1 )/step)
LOOP
var_unencoded_raw := utl_raw.cast_to_raw(dbms_lob.substr(attachment_clob_5, step, i * step + 1));
var_encoded_raw := utl_encode.base64_encode(var_unencoded_raw);
var_encoded_string := utl_raw.cast_to_varchar2(var_encoded_raw);
utl_smtp.write_data(mail_connection, var_encoded_string);
END LOOP;
utl_smtp.write_data(mail_connection, utl_tcp.CRLF || utl_tcp.CRLF);
END IF;
utl_smtp.write_data(mail_connection, '--' || boundary || '--' || utl_tcp.crlf);
utl_smtp.close_data(mail_connection);
utl_smtp.quit(mail_connection);
END;
/
这是在正文中启用的 HTML。 我有另一个是纯文本。 我喜欢 HTML 这样我就可以做一些简单的格式化,比如粗体和斜体等等。
然而,我的附件往往是文本,即使 CSV 或 XML 用于 Excel。所以,我总是使用 mime 'text/plain'
作为我的附件。 将您的附件编译为 CLOB 并将其传递到其中一个附件参数中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.