Beim Betrieb einer Oracle Apex-Anwendung ist es oft notwendig tabellarische SQL-Berichte per Mail zu versenden. Dies kann eine Admin-Mail über den Zustand der Apex-Anwendung sein aber auch inhaltliche Benachrichtigungen an bestimmte Benutzerkreise oder Stakeholder der Apex-Anwendung. Gerade im Letzteren Fall sollte die Formatierung des SQL-Berichtes stimmen und das Layout ansprechend sein. Auf Nummer sicher geht man, wenn man in diesem Fall einen PDF-Bericht erzeugt und ihn im Anhang der Mail mitsendet. Dies ist allerdings auch entsprechend aufwendig.
Als einfachere Alternative bietet sich an, den SQL-Bericht als HTML-Tabelle in einer HTML-Mail per Apex Mail zu versenden.
Im Folgenden stelle ich eine generische Funktion vor, die einen beliebigen SQL-Select ausführt und die Ergebnismenge als HTML-Tabelle rendered.
Zusätzlich stelle ich ein Beispielskript vor, das die HTML-Tabelle per Apex Mail versendet. Dabei bereite ich das Layout des Berichts über mehrere allgemeine CSS-Regeln auf.
Funktion PRINT_RESULT:
Hierbei habe ich einfach die Funktion in http://www.java2s.com/Tutorial/Oracle/0601__System-Packages/Printtablewithdynamicquery.htm um die HTML-Option erweitert.
create or replace FUNCTION "PRINT_RESULT" ( p_query IN VARCHAR2, p_markup IN VARCHAR2 DEFAULT 'TEXT')
RETURN CLOB
AUTHID CURRENT_USER
IS
/**
* Prints the result of the SQL-Statement (p_query) as TEXT-Output or HTML-Output (p_markup)
* This function enhances the following code
* http://www.java2s.com/Tutorial/Oracle/0601__System-Packages/Printtablewithdynamicquery.htm
*/
l_theCursor INTEGER DEFAULT dbms_sql.open_cursor;
l_columnValue VARCHAR2(32676);
l_status integer;
l_descTbl dbms_sql.desc_tab;
l_colCnt number;
l_even BOOLEAN;
l_row_css VARCHAR2(1000);
l_return_str CLOB :='';
BEGIN
DBMS_SESSION.SET_ROLE('ALL');
dbms_sql.parse(l_theCursor,p_query,dbms_sql.native);
dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl);
for i in 1 .. l_colCnt loop
dbms_sql.define_column(l_theCursor, i, l_columnValue, 4000);
end loop;
l_status := dbms_sql.execute(l_theCursor);
IF p_markup = 'HTML' THEN
l_return_str := l_return_str || '
'; END IF;for i in 1 .. l_colCnt loop
l_columnValue := l_descTbl(i).col_name;
IF p_markup = 'HTML' THEN
l_columnValue := ''|| l_columnValue || '
';
END IF;
l_return_str := l_return_str ||substr(l_columnValue, 0, 300);
end loop;
IF p_markup = 'HTML' THEN
l_return_str := l_return_str || '
';
ELSE
for i in 1 .. l_colCnt loop
l_return_str := l_return_str || rpad( '----', 200, '-' );
end loop;
END IF;
l_return_str := l_return_str ||CHR(10);
l_even := FALSE;
while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
IF p_markup = 'HTML' THEN
IF l_even THEN
l_row_css := 'style="background-color:#f5f5ff;"';
ELSE
l_row_css := '';
END IF;
l_return_str := l_return_str || '
<tr '||l_row_css||'>';
END IF;
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor, i, l_columnValue );
IF p_markup = 'HTML' THEN
l_columnValue := ''||l_columnValue || '
';
END IF;
l_return_str := l_return_str || substr(l_columnValue, 0, 300);
end loop;
IF NOT l_even THEN
l_even := TRUE;
ELSE
l_even := FALSE;
END IF;
IF p_markup = 'HTML' THEN
l_return_str := l_return_str || '
';
END IF;
l_return_str := l_return_str || CHR(10);
end loop;
IF p_markup = 'HTML' THEN
l_return_str := l_return_str || '
';
END IF;
RETURN l_return_str;
EXCEPTION
when others then dbms_sql.close_cursor( l_theCursor ); RAISE;
END;
/
Versand der Apex-Mail inkl. CSS-Regeln:
declare
l_mail_text CLOB;
l_mail_text_html CLOB;
l_statement VARCHAR2(32676);
l_mail_id NUMBER;
PROCEDURE setup_apex_mail
IS
l_security_group_id NUMBER;
BEGIN
SELECT workspace_id
INTO l_security_group_id
FROM apex_workspaces
WHERE workspace='YOUR_WORKSPACE'; /* Use your workspace name here */
wwv_flow_api.set_security_group_id(l_security_group_id);
END;
FUNCTION get_html_mail_header
RETURN VARCHAR2
IS
l_home_url VARCHAR2(1000);
BEGIN
l_home_url := 'intranet.home-site';
RETURN '<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="CONTENT-TYPE" />
<style type="text/css">#content, body { color:#324242; font-family: Arial, sans-serif; width:60em; border:1px solid #EEE; padding:3em 5em 5em; margin:2em; } body { color:#324242; } a { color:#1F4F80; } .i
nfo { font-size:75%; color:#324242; padding:0; } .details { background:#1F4F80 none repeat scroll 0 0; color:#CDD6DF; font-weight:normal; border:2px solid #F18900; text-align:left; } .content th { col
or:#CDD6DF; font-weight:normal; } .details td { color:#ffffff; font-weight:bold; } .header { background:#1F4F80 none repeat scroll 0 0; border:2px solid #F18900; text-align:center; border-collapse:col
lapse; color:#CDD6DF; } .header td { padding:4px 0; } .detailsth { background:#1F4F80; color:#4D5508; font-weight:bold; color:#ffffff; } .event { margin:auto; text-align:center; width:85%; } .statusDe
scr { font-size:0.85em; line-height:2em; } .hide { display: none; } td {border:1px solid #999;} th {border:1px solid #99b; background-color:#dde;} </style>
</head>
<body text="#000000" bgcolor="#ffffff">
<div id="content">
<a href="'||l_home_url||'">
<i>Home-Site</i>
</a>
<div style="display:none">
<br/><br/><br/>
to display this HTML-Mail properly <br/>
enable **HTML-format** in your Mail-client <br/>
</div>
<br />
<br />
<br />
<b>Hello ,</b>
<br />
<br />';
END;
FUNCTION get_html_mail_footer
RETURN VARCHAR2
IS
BEGIN
RETURN '
<br />
<br />
<br />
<b>
<span class="firstLetter">Regards,</span>
</b>
<br />
<br />
Your ApexTipps-Team
<br />
<br />
This email is being sent automatically, please do not answer it
</div>
</body>
</html></div>';
END;
BEGIN
l_mail_text := get_html_mail_header;
l_mail_text := l_mail_text || 'Apex DB-Info '||'<br/>'||'<br/>'||sysdate;
l_statement := 'select owner, table_name, tablespace_name, status, num_rows
from all_tables
where owner=''HR''';
l_mail_text := l_mail_text || '<br/>' ||'<br/>' || '<strong>HR-Tables</strong> '||'<br/>'||'<br/>'||
print_result(l_statement, 'HTML');
l_mail_text := l_mail_text || get_html_mail_footer;
setup_apex_mail;
l_mail_id := apex_mail.send(
p_to => 'some.address@email.domain', -- change to your email address
p_from => 'some.address@email.domain',
p_subj => '[Apex-Info] Query-Report',
p_body => l_mail_text,
--p_body => null,
p_body_html=> l_mail_text);
end;
/
BEGIN
APEX_MAIL.PUSH_QUEUE;
END;
/

Pingback: Sending a tabular HTML report via APEX Mail | Notes by Jens Marre