rem rem $Header: dbmsmail.sql,v 1.11 1993/04/20 18:38:36 RKOOI Exp $ rem Rem Copyright (c) 1991 by Oracle Corporation Rem NAME Rem dbmsmail.sql - send ora*mail Rem DESCRIPTION Rem Rem RETURNS Rem Rem NOTES Rem The procedural option is needed to use this facility. Rem Rem NOTE for Upgrade from versions prior to 7.0.14: Rem You will need to create the view 'dbms_mail.v$myclientinfo' Rem under schema 'sys' as described in step (3) belo. Rem Rem MODIFIED (MM/DD/YY) Rem rkooi 04/20/93 - merge changes from branch 1.10.312.1 Rem rkooi 04/07/93 - security improvements Rem rkooi 09/30/92 - add some comments Rem rkooi 09/02/92 - change ORU errors Rem rkooi 06/10/92 - add rae errors Rem rkooi 01/10/92 - Creation rem create or replace package dbms_mail as ----------- -- OVERVIEW -- -- This package is an interface to the Oracle*Mail product. You can -- send an Oracle*Mail message by calling the 'send' procedure. The mail -- will be sent when the transaction is committed. This procedure -- can be called from a trigger. This package will work with Version 1.1 -- of Oracle*Mail. --------- -- SETUP -- -- Before creating this package, you must -- -- 1) Run the 'utlmail.sql' script on the mail database (with -- Oracle*Mail Version 1.1 installed) as user 'email'. Then create -- a special database account in the mail database, -- /, with connect privilege only: -- -- create user identified by ; -- grant connect to ; -- -- Then make a valid Oracle*Mail user. -- -- 2) Create a database account in the database from which you wish -- to send email. This is so the following database link is not -- widely accessible and so that you can control who has access -- to this package. Assume this account is named . -- -- Connect to and create a database link named -- which points to the mail database: -- -- create database link connect to identified by -- using '...'; -- -- As mentioned in step (1), must be a valid Oracle*Mail -- user for the mail database AND / must be -- a valid DATABASE user in the mail database (but should only have -- "connect" permission). -- -- In order for "global naming" to be enabled, the node name must be -- the same as the name of the database. See the DBA Guide for -- more information on global naming. If global naming is -- disabled for this database, then the name of the database link -- is not important. -- -- 3) In the database from which you wish to send email, create the -- dbms_mail$myclientinfo view: -- -- connect sys/chg_on_install -- create or replace view dbms_mail$myclientinfo as -- select ' [SENDER=(' || -- substr(osuser || ',' || user || ',' || machine || ',' || -- program || ',' || terminal || ',' || process, 1, 58) -- || ')]' clientinfo -- from v$session where sid = -- (select sid from v$mystat where rownum = 1); -- grant select on dbms_mail$myclientinfo to ; -- -- 4) Using the database link name chosen in step (2), create the -- following synonyms for use by this package: -- create synonym mail_info for email.s_sender_info@; -- create synonym mail_header for email.s_send_header@; -- create synonym mail_instance for email.s_send_instance@; -- create synonym mail_body for email.s_send_body@; -- create synonym mail_name for email.s_user_name@; -- create synonym mail_seq for email.m_id_seq@; -- -- 5) Do a "select * from dual@;" to make sure the node is -- reachable. -- -- 6) Run this script -- -- If your account does not have the privileges to create the public -- synonym at the end of this script then connect as internal or 'sys' -- to create the synonym. If the public synonym is not created then -- the user must invoke the package as -- .dbms_mail.send(...) -- rather than -- dbms_mail.send(...) -- where is the name chosen above. -- -- If points to a V6 database then you cannot call this -- procedure from a trigger since that requires distributed transactions. -- -- The distributed and procedural extensions are required to use this -- feature. ------------------------ -- EXAMPLE INSTALLATION -- -- You need to substitute appropriate values wherever you see <>'s. -- -- ***Do this for the mail database*** -- connect email/ -- @ora_system:utlmail.sql -- connect sys/chg_on_install -- grant connect to sp_mailer identified by ; -- -- -- ***Do this for each database from which you want to send mail*** -- connect / -- create database link maildb connect to sp_mailer identified by -- using ''; -- select * from dual@maildb; -- create synonym mail_info for email.s_sender_info@maildb; -- create synonym mail_header for email.s_send_header@maildb; -- create synonym mail_instance for email.s_send_instance@maildb; -- create synonym mail_body for email.s_send_body@maildb; -- create synonym mail_name for email.s_user_name@maildb; -- create synonym mail_seq for email.m_id_seq@maildb; -- connect sys/chg_on_install -- create or replace view dbms_mail$myclientinfo as -- select ' [SENDER=(' || -- substr(osuser || ',' || user || ',' || machine || ',' || -- program || ',' || terminal || ',' || process, 1, 58) -- || ')]' clientinfo -- from v$session where sid = -- (select sid from v$mystat where rownum = 1); -- grant select on dbms_mail$myclientinfo to ; -- connect / -- @ora_system:dbmsmail.sql -- execute dbms_mail.send('test-from', '', 'cc-str', 'bcc-str', -- 'test subject', '', 'test body'); -- commit -- *** should now receive the mail! --------------------------- -- PROCEDURES AND FUNCTIONS -- procedure send(from_str in varchar2, to_str in varchar2, cc in varchar2, bcc in varchar2, subject in varchar2, reply_to in varchar2, body in varchar2); -- The send procedure sends and Oracle*Mail message to the specified -- recipients. The message is actually sent when the transaction -- in which this call is made commits. Consult the ORA*MAIL product -- form information on size limits for the following arguments. -- Input parameters: -- from_str -- This is the alternate name for the sender of this message. Must -- be <= 10 bytes long. May be null. Information about the client -- process is also included as part of the sender information. -- to_str -- A comma or space separated list of Oracle*Mail users to send this -- message to. -- cc -- A comma or space separated list of Oracle*Mail users to copy. -- bcc -- A comma or space separated list of Oracle*Mail users to blind copy. -- subject -- The subject heading for this message. -- reply_to -- The reply-to line for this message. -- body -- The message body, up to 2000 bytes. -- Errors raised: -- -20000, ORU-10014: user does not have an Oracle*Mail -- account on the mail node. -- Cause: The user named in the 'maildb' database link must have -- been given an Oracle*Mail account on the mail database. The -- account need have no privileges other than 'connect'. -- end; / create or replace package body dbms_mail as user_id number; user_node number; msg_node number; sender_name varchar(81); name_at_mailnode varchar2(30); client_id varchar2(70); procedure send(from_str varchar2, to_str varchar2, cc varchar2, bcc varchar2, subject varchar2, reply_to varchar2, body varchar2) is order_no number; pos number; bsize number; len number; smallbody varchar2(240); f_str varchar2(80) := from_str; begin -- Accurately (as possible) identify the real user based on the actual -- client process. It is easy for dba's to create database accounts -- with arbitrary names so don't rely on those. f_str := substr(f_str,1,10) || client_id; begin if user_id IS NULL then select sender_name, msg_node, user_id, user_node into sender_name, msg_node, user_id, user_node from mail_info; end if; exception when no_data_found then raise_application_error(-20000, 'ORU-10014: user "' || name_at_mailnode || '" does not have an Oracle*Mail account on the mail node'); end; insert into mail_header (msg_id, msg_node, type, part_type, hdr_flags, sender_id, sender_node, sender_date, reply_to, to_str, cc_str, bcc_str, subject, from_str, sender_name, deferred, inclusion_id, inclusion_node) values (mail_seq.nextval, msg_node, 1, 0, 0, user_id, user_node, sysdate, reply_to, to_str, cc, bcc, subject, f_str, sender_name, 'N', 0, 0); insert into mail_instance (msg_id, msg_node, node_id, msg_owner, folder_id, retention_date, unread_flag, flags) values (mail_seq.currval, msg_node, user_node, user_id, 2, sysdate, 'Y', 0); order_no := 1; pos := 1; bsize := length(body); while bsize > 0 loop if bsize > 240 then len := 240; else len := bsize; end if; -- compute substr here because the entire query below is sent -- to the remote site, and V6 can't handle longs (body is a long) smallbody := substr(body,pos,len); insert into mail_body (msg_id, msg_node, part, order_no, msg_line) values (mail_seq.currval, msg_node, 0, order_no, smallbody); order_no := order_no + 1; pos := pos + len; bsize := bsize - len; end loop; end; begin -- for error messages select user_name into name_at_mailnode from mail_name; -- get client info to more accurately identify who is sending this email select clientinfo into client_id from sys.dbms_mail$myclientinfo; end; / drop public synonym dbms_mail / create public synonym dbms_mail for dbms_mail /