email - liamlamth/blog GitHub Wiki
-
reference: https://oracle-base.com/articles/misc/email-from-oracle-plsql
-
required ACL
### check before action select * from dba_network_acls; ### the existing host and its assigned xml select * from dba_network_acl_privileges; ### the xml and its assigned schema(s) ### add priviledge if a host is already assigned to any xml begin dbms_network_acl_admin.add_privilege ( acl => 'acl_file.xml', principal => 'email_user', is_grant => true, privilege => 'connect', position => null, start_date => null, end_date => null); commit; end; / ### if the ACL xml hasn't been created ### if try to assign a assigned host to another xml, it will replace the original. be aware. dbms_network_acl_admin.create_acl dbms_network_acl_admin.assign_acl
-
required package
create or replace package string_api as type t_split_array is table of varchar2(4000); function split_text (p_text in clob, p_delimeter in varchar2 default ',') return t_split_array; procedure print_clob (p_clob in clob); procedure print_clob_old (p_clob in clob); procedure print_clob_htp (p_clob in clob); procedure print_clob_htp_old (p_clob in clob); function get_uri_paramter_value (p_uri in varchar2, p_param_name in varchar2) return varchar2; end string_api; / create or replace package body string_api as type t_uri_array is table of varchar2(32767) index by varchar2(32767); g_last_uri varchar2(32767) := 'initialized'; g_uri_tab t_uri_array; ------------------------------------------------------------------------------ function split_text (p_text in clob, p_delimeter in varchar2 default ',') return t_split_array is -- Could be replaced by APEX_UTIL.STRING_TO_TABLE. l_array t_split_array := t_split_array(); l_text clob := p_text; l_idx number; begin l_array.delete; if l_text is null then raise_application_error(-20000, 'P_TEXT parameter cannot be NULL'); end if; while l_text is not null loop l_idx := instr(l_text, p_delimeter); l_array.extend; if l_idx > 0 then l_array(l_array.last) := substr(l_text, 1, l_idx - 1); l_text := substr(l_text, l_idx + 1); else l_array(l_array.last) := l_text; l_text := null; end if; end loop; return l_array; end split_text; ------------------------------------------------------------------------------- procedure print_clob (p_clob in clob) is l_offset number := 1; l_chunk number := 255; begin loop exit when l_offset > length(p_clob); dbms_output.put_line(substr(p_clob, l_offset, l_chunk)); l_offset := l_offset + l_chunk; end loop; end print_clob; ------------------------------------------------------------------------------- procedure print_clob_old (p_clob in clob) is l_offset number := 1; l_chunk number := 255; begin loop exit when l_offset > dbms_lob.getlength(p_clob); dbms_output.put_line(dbms_lob.substr(p_clob, l_offset, l_chunk)); l_offset := l_offset + l_chunk; end loop; end print_clob_old; ------------------------------------------------------------------------------- procedure print_clob_htp (p_clob in clob) is l_offset number := 1; l_chunk number := 3000; begin loop exit when l_offset > length(p_clob); htp.prn(substr(p_clob, l_offset, l_chunk)); l_offset := l_offset + l_chunk; end loop; end print_clob_htp; ------------------------------------------------------------------------------- procedure print_clob_htp_old (p_clob in clob) is l_offset number := 1; l_chunk number := 3000; begin loop exit when l_offset > dbms_lob.getlength(p_clob); htp.prn(dbms_lob.substr(p_clob, l_offset, l_chunk)); l_offset := l_offset + l_chunk; end loop; end print_clob_htp_old; ------------------------------------------------------------------------------- function get_uri_paramter_value (p_uri in varchar2, p_param_name in varchar2) return varchar2 is ------------------------------------------------------------------------------- -- Example: -- l_uri := 'https://localhost:8080/my_page.php?param1=value1¶m2=value2¶m3=value3'; -- l_value := string_api.get_uri_paramter_value(l_uri, 'param1') ------------------------------------------------------------------------------- l_uri varchar2(32767); l_array t_split_array := t_split_array(); l_idx number; begin if p_uri is null or p_param_name is null then raise_application_error(-20000, 'p_uri and p_param_name must be specified.'); end if; if p_uri != g_last_uri then -- First time we've seen this URI, so build the key-value table. g_uri_tab.delete; g_last_uri := p_uri; l_uri := translate(g_last_uri, '&?', '^^'); l_array := split_text(l_uri, '^'); for i in 1 .. l_array.count loop l_idx := instr(l_array(i), '='); if l_idx != 0 then g_uri_tab(substr(l_array(i), 1, l_idx - 1)) := substr(l_array(i), l_idx + 1); end if; end loop; end if; return g_uri_tab(p_param_name); exception when no_data_found then return null; end get_uri_paramter_value; end string_api; /
-
required procedure
create or replace procedure send_mail (p_to in varchar2, p_cc in varchar2 default null, p_bcc in varchar2 default null, p_subject in varchar2, p_html_msg in varchar2 default null, p_attach_name in varchar2 default null, p_attach_mime in varchar2 default null, p_attach_blob in blob default null, p_send_time in varchar2 default null, p_from in varchar2 default '[email protected]', p_smtp_host in varchar2 default 'smtphost.domain.local', p_smtp_port in number default 25) as l_mail_conn utl_smtp.connection; l_boundary varchar2(50) := '----=*#abc1234321cba#*='; l_step pls_integer := 57; l_send_time varchar2(100); procedure process_recipients(p_mail_conn in out utl_smtp.connection, p_list in varchar2) as l_tab string_api.t_split_array; begin if trim(p_list) is not null then l_tab := string_api.split_text(p_list); for i in 1 .. l_tab.count loop utl_smtp.rcpt(p_mail_conn, trim(l_tab(i))); end loop; end if; end; begin l_mail_conn := utl_smtp.open_connection(p_smtp_host, p_smtp_port); utl_smtp.helo(l_mail_conn, p_smtp_host); utl_smtp.mail(l_mail_conn, p_from); process_recipients(l_mail_conn, p_to); process_recipients(l_mail_conn, p_cc); process_recipients(l_mail_conn, p_bcc); utl_smtp.open_data(l_mail_conn); if p_send_time is not null then l_send_time := to_char( to_timestamp_tz(p_send_time,'YYYY-MM-DD'), 'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE=ENGLISH'); else l_send_time := to_char( systimestamp, 'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE=ENGLISH'); end if; utl_smtp.write_data(l_mail_conn, 'Date: ' || l_send_time || utl_tcp.crlf); utl_smtp.write_data(l_mail_conn, 'To: ' || p_to || utl_tcp.crlf); if trim(p_cc) is not null then utl_smtp.write_data(l_mail_conn, 'CC: ' || replace(p_cc, ',', ';') || utl_tcp.crlf); end if; if trim(p_bcc) is not null then utl_smtp.write_data(l_mail_conn, 'BCC: ' || replace(p_bcc, ',', ';') || utl_tcp.crlf); end if; utl_smtp.write_data(l_mail_conn, 'From: ' || p_from || utl_tcp.crlf); utl_smtp.write_raw_data(l_mail_conn, utl_raw.cast_to_raw('Subject: '|| replace(utl_encode.mimeheader_encode(p_subject, 'utf8'),chr(13)||chr(10),'') || utl_tcp.crlf)); utl_smtp.write_data(l_mail_conn, 'Reply-To: ' || p_from || utl_tcp.crlf); utl_smtp.write_data(l_mail_conn, 'MIME-Version: 1.0' || utl_tcp.crlf); utl_smtp.write_data(l_mail_conn, 'Content-Type: multipart/alternative; boundary="' || l_boundary || '"' || utl_tcp.crlf || utl_tcp.crlf); utl_smtp.write_data(l_mail_conn, '--' || l_boundary || utl_tcp.crlf); utl_smtp.write_data(l_mail_conn, 'Content-Type: text/html; charset="utf-8"' || utl_tcp.crlf || utl_tcp.crlf); utl_smtp.write_raw_data(l_mail_conn, utl_raw.cast_to_raw(p_html_msg)); utl_smtp.write_data(l_mail_conn, utl_tcp.crlf || utl_tcp.crlf); if p_attach_name is not null then utl_smtp.write_data(l_mail_conn, '--' || l_boundary || utl_tcp.crlf); utl_smtp.write_raw_data(l_mail_conn, utl_raw.cast_to_raw('Content-Type: ' || p_attach_mime || '; name="' || p_attach_name || '"; charset="utf-8"' || utl_tcp.crlf)); utl_smtp.write_data(l_mail_conn, 'Content-Transfer-Encoding: base64' || utl_tcp.crlf); utl_smtp.write_raw_data(l_mail_conn, utl_raw.cast_to_raw('Content-Disposition: attachment; filename="' || p_attach_name || '"' || utl_tcp.crlf || utl_tcp.crlf)); for i in 0 .. trunc((dbms_lob.getlength(p_attach_blob) - 1 )/l_step) loop utl_smtp.write_data(l_mail_conn, utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_lob.substr(p_attach_blob, l_step, i * l_step + 1))) || utl_tcp.crlf); end loop; utl_smtp.write_data(l_mail_conn, utl_tcp.crlf); end if; utl_smtp.write_data(l_mail_conn, '--' || l_boundary || '--' || utl_tcp.crlf); utl_smtp.close_data(l_mail_conn); utl_smtp.quit(l_mail_conn); end; /
-
usage
declare v_blob blob; begin send_mail('[email protected]','[email protected],[email protected]',null, ### delimiter for multiple recipients must be "," 'Test Message','<html><p>This is a test message.</p></html>', 'test.png','image/png',v_blob, ### (optional) attachment '2022-01-01' ### (optional) fake send time ) end; /