PL/SQL - e-maily s prilohou z Oracle DB
Hodnotenie čitateľov: / 2
SlabéVynikajúce 
Oracle logoTak 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 :(
Posledná úprava ( Tuesday, 11 November 2008 )
 
< Predchádzajúca   Ďalšia >