Я могу поделиться пакетом, который я использую; да, теперь я вижу, что это было написано, пока еще не было LISTAGG
, поэтому не стесняйтесь исправить это, если хотите.
CREATE OR REPLACE PACKAGE BODY pkg_sys
AS
PROCEDURE p_users_to_expire
AS
l_users_to_expire VARCHAR2 (300);
BEGIN
SELECT RTRIM (
XMLAGG (XMLELEMENT (
e,
u.username
|| ' '
|| TO_CHAR (u.expiry_date, 'dd.mm.yyyy')
|| CHR (13)) ORDER BY u.username).EXTRACT (
'//text()'),
CHR (13))
INTO l_users_to_expire
FROM dba_users u
WHERE TRUNC (u.expiry_date) > SYSDATE
AND TRUNC (u.expiry_date) - TRUNC (SYSDATE) < 14; --> 2 weeks
IF l_users_to_expire IS NOT NULL
THEN
for cur_r in (select 'littlefoot@xyz.com' recipient from dual union all
select 'bigfoot@xyz.com' recipient from dual
)
loop
pkg_sys.p_send_mail (
par_from => 'dba@xyz.com',
par_recipient => cur_r.recipient,
par_subject => 'Users to expire',
par_mail_host => NULL,
par_msg_text => l_users_to_expire);
end loop;
END IF;
END p_users_to_expire;
PROCEDURE p_send_mail (par_from IN VARCHAR2,
par_recipient IN VARCHAR2,
par_subject IN VARCHAR2,
par_mail_host IN VARCHAR2,
par_msg_text IN VARCHAR2)
AS
v_Mail_Host VARCHAR2 (30) := NVL (par_mail_host, 'mail.xyz.com');
v_Mail_Conn UTL_SMTP.Connection;
crlf VARCHAR2 (2) := CHR (13) || CHR (10);
BEGIN
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, par_From);
UTL_SMTP.Rcpt (v_Mail_Conn, par_Recipient);
UTL_SMTP.Data (
v_Mail_Conn,
'Date: '
|| TO_CHAR (SYSDATE, 'Dy, DD Mon YYYY hh24:mi:ss')
|| crlf
|| 'From: '
|| par_From
|| crlf
|| 'Subject: '
|| par_Subject
|| crlf
|| 'To: '
|| par_Recipient
-- 2 CRLFs
|| crlf
|| crlf
-- message text
|| par_msg_text
|| crlf);
UTL_SMTP.Quit (v_mail_conn);
EXCEPTION
WHEN UTL_SMTP.Transient_Error OR UTL_SMTP.Permanent_Error
THEN
raise_application_error (-20000, 'Unable to send mail: ' || SQLERRM);
END p_send_mail;
END pkg_sys;
/