Tak a predsa sa mi to podarilo. V piatok som dostal za ulohu vyhutat ako nasa aplikacia (spocinajuca z PL/SQL balikov ulozenych v Oracle scheme) bude odosielat e-mailove spravy s prilohou PDF suborov. Prvy pocit - to bude jednoduche. Po kratkom Googleni som vsak usudil, ze sa jedna o trosku zlozitejsiu ulohu nez som ocakaval. Preco v dnesnej dobe su tak primitivne veci tak zlozito urobitelne. Skoda, ze som nenasiel hned na prvy pokus jednoduchy kompletny postup, ako docielit to po com tuzim. A chcem toho v 21. storoci tak vela? E-mail s prilohou? Bolo mi potrebne otocit si hlavu okolo niekolkych principov.
Situacia
Oracle 10g, napomocny DBA, IP adresa SMTP servra. To su tri veci, ktore som mal k dispozicii. Zvysok som si vygooglil sam, a mal som pri tom veru dost stastia.
Nebudem sa prilis rozpisovat, uvediem kroky ako som siel na vec (resp. ako by bolo idealne keby som bol siel na vec):
Poziadal som nasho DBA (databazoveho administratora), aby nasu instalaciu Oracle 10g obohatil o pridavny balicek (package) UTL_MAIL. Uistil som sa, ze nasa instalacia obsahuje balicek UTL_FILE. Poziadal som DBA, aby nastavil databazovy parameter SMTP_OUT_SERVER na znamu IP adresu nasho servra odchodzej posty. Uistil som sa, ze port 25 (pouzivany protokolom SMTP) je prechodny - ze ho neblokuje taky ci inaky Antivirus. Dalsia laskavost, o ktoru som poziadal nasho laskaveho DBA, bolo nastavenie pristupovych prav Oracle-u k suborom v suborovom systeme. Vytvoril pre mna alias 'MOJA_ZLOZKA' pre zlozku na suborovom systeme 'C:\mojaZlozka' a prisudil mi (ako Oracle uzivatelovi) pravo citania suborov v tejto zlozke. Do takto nastaveneho prostredia som mohol zacat vkladat potrebny PL/SQL kod.
Mozno sa zda, ze vsetku pracu vlastne vykonal DBA. V skutocnosti sa jednalo o nikolko klikov a stukov. Vsetko hotove v priebehu par okamihov. Kazdy sebelepsi DBA ma dostatocne znalosti aby tieto veci nastavil bez toho aby sa clovek - bezny programator - musel do toho prilis vidiet. Zhrnutie- "nainstalovat" package UTL_MAIL
- nastavit DB parameter SMTP_OUT_SERVER
- vytvorit zlozku v suborovom systeme a zaregistrovat jej lokaciu v Oracle-i vytvorenim aliasu pre tuto zlozku ako napr. MOJA_ZLOZKA
- uistit sa, ze UTL_FILE package existuje
- a ze nic nebrani komunikacii na porte 25.
Rozhodol som sa, ze si vytvoril svoj vlastny balicek s uzitocnymi procedurami pre odosielanie e-mailov s prilohou. Vytvoril som si subor EMAIL_UTILS.sql, do ktoreho som si nachystal, rad-radom, specifikaciu balicka (package structure), aj samotne telo balicka (package body). Potom je dost jednoduche takto nadefinovany package vytvorit na servri pomocou sqlplus. Kod balicka darujem gratis, ved je celkom lahko najditelny na internete, stacilo by kusok viac pogooglit. No vzdy uvadzanemu kodu co-to chyba alebo prebyva, tak si myslim, ze je fajn ked tu uvediem presne to, co ste asi hladali :)
CREATE OR REPLACE PACKAGE EMAIL_UTILS AS
PROCEDURE SendMailWithAttachment
( p_From VARCHAR2,
p_Recipient VARCHAR2,
p_Subject VARCHAR2,
p_Message VARCHAR2,
p_AttMimeType VARCHAR2,
p_FileName VARCHAR2
);
PROCEDURE SendMailWithPDF
( p_From VARCHAR2,
p_Recipient VARCHAR2,
p_Subject VARCHAR2,
p_Message VARCHAR2,
p_FileName VARCHAR2
);
END EMAIL_UTILS;
/
Show Errors
CREATE OR REPLACE PACKAGE BODY EMAIL_UTILS AS
g_FileNotFoundException EXCEPTION;
g_defaultMessageSubject VARCHAR2(100) := 'Message Subject';
--send email with ANY type of attachment
PROCEDURE SendMailWithAttachment
( p_From VARCHAR2,
p_Recipient VARCHAR2,
p_Subject VARCHAR2,
p_Message VARCHAR2,
p_AttMimeType VARCHAR2,
p_FileName VARCHAR2
) IS
l_Subject VARCHAR2(100) :=
Nvl(p_Subject, g_defaultMessageSubject);
vInHandle utl_file.file_type;
rfile RAW(32767); --max file size
flen NUMBER := 0; --file size
bsize NUMBER := 0; --file system block size
ex BOOLEAN; --does the file exist?
BEGIN
utl_file.fgetattr(
'MOJA_ZLOZKA', p_FileName, ex, flen, bsize
);
IF (ex=FALSE) THEN
RAISE g_FileNotFoundException;
ELSE
vInHandle := utl_file.fopen(
'MOJA_ZLOZKA', p_FileName, 'RB'
);
utl_file.get_raw(vInHandle, rfile, flen);
utl_file.fclose(vInHandle);
UTL_MAIL.SEND_ATTACH_RAW (
sender => p_From,
recipients => p_Recipient,
subject => l_Subject,
message => p_Message,
attachment => rfile,
att_inline => FALSE,
att_mime_type => p_AttMimeType,
att_filename => p_FileName);
END IF;
END SendMailWithAttachment;
--send e-mail with PDF attachment
PROCEDURE SendMailWithPDF
( p_From VARCHAR2,
p_Recipient VARCHAR2,
p_Subject VARCHAR2,
p_Message VARCHAR2,
p_FileName VARCHAR2
) IS
BEGIN
SendMailWithAttachment(
p_From => p_From,
p_Recipient => p_Recipient,
p_Subject => p_Subject,
p_Message => p_Message,
p_AttMimeType => 'application/pdf',
p_FileName => p_FileName
);
END SendMailWithPDF;
END EMAIL_UTILS;
/
Show Errors
Skuska
Po uspesnom vytvoreni a kompilacii tohto balicka, mozeme zacat vyuzivat jeho ponukane funkcie. Tak napriklad, ak mame v zlozke na ktoru poukazuje alias 'MOJA_ZLOZKA' umiestneny subor pdfdocument.pdf - v nasom priklade to bola zlozka C:\mojaZlozka - mohli by sme potom tento subor odoslat ako prilohu s e-mailom jednoduchym zavolanim:
email_utils.sendmailwithpdf(
'
Táto e-mailová adresa je chránená pred spamovými robotmi, potrebujete mať zapnutý Javascript aby ste ju mohli vidieť.
',
'
Táto e-mailová adresa je chránená pred spamovými robotmi, potrebujete mať zapnutý Javascript aby ste ju mohli vidieť.
',
'subject',
'message text',
'pdfdocument.pdf'
); z PL/SQL akehokolvek ineho balicka (nasej aplikacie).
Ak by ste si chceli odosielanie e-mailov s PDF prilohou skusit priamo z sqlplus konzoly, uvedte volanie tejto procedury za prikaz exec exec email_utils.sendmailwithpdf(
'
Táto e-mailová adresa je chránená pred spamovými robotmi, potrebujete mať zapnutý Javascript aby ste ju mohli vidieť.
',
'
Táto e-mailová adresa je chránená pred spamovými robotmi, potrebujete mať zapnutý Javascript aby ste ju mohli vidieť.
',
'subject',
'message text',
'pdfdocument.pdf'
)
Poznamky
- vsimnite si velkost RAW objektu - 32k, to je maximalna velkost suboru, ktory takto mozete pripnut k e-mailu. Pokusal som sa tento smiesny limit obist, no zatial neuspesne. Balicek UTL_MAIL neobsahuje proceduru, ktora by odosielala BLOB attachmenty. A RAW data type ma maximalnu velkost 32767 bytov :(
|