Auswahl  

 

Oracle
DBA
12.1, 12.2
UTL_MAIL, Email Versand aus der Datenbank
11.12.18
MP
11.12.18
MP

Body

Vorbereitungen

Folgende Schritte müssen durchgeführt werden, damit das Package eingesetzt werden kann:Installation:

  1. Konfiguration des SMTP-Servers:
    Der INIT<SID>.ora-Parameter SMTP_OUT_SERVER muss gesetzt werden; da dies im laufenden Betrieb (bis 10.2.0.3) nicht möglich ist, muss die Datenbank hinterher durchgestartet werden. Ab Version 10.2.0.4 kann der Parameter im laufenden Betrieb verändert werden. Angegeben wird der Name des SMTP-Servers, optional kann noch die Portnummer ergänzt werden. Wird keine Portnummer angegeben, so wird als Default Port 25 verwendet.
     
  2. EXECUTE-Recht an dem Package vergeben:
    GRANT execute on sys.utl_mail TO scott;

Beispiel:

SQL> CONN / AS SYSDBA
SQL> ALTER SYSTEM SET SMTP_OUT_SERVER='myemailserver' SCOPE=SPFILE;
...
SQL> GRANT EXECUTE ON UTL_MAIL TO scott;

Mails versenden:

UTL_MAIL bietet drei Prozeduren zum Versenden von E-Mails:

  • SEND: Versenden einfacher Mails ohne Anhang
  • SEND_ATTACH_RAW: Versenden von Mails mit binärem Anhang
  • SEND_ATTACH_VARCHAR2: Versenden von Mails mit Textanhang

Minimal müssen bei allen drei Prozeduren Sender, Empfänger und Mailtext angegeben werden. Bei mehr als einem Empfänger werden die Adressen durch Kommata getrennt. cc, bcc und subject (Betreff) können noch optional angegeben werden, ebenso wie mime_type (Default: 'text/plain; charset=us-ascii') und priority. Der Einsatz von SEND ist sehr einfach.

Beispiel:

DECLARE
   v_msg VARCHAR2(32767);
   cr VARCHAR2(4000);
BEGIN                
   cr := CHR(13)||CHR(10);    
   v_msg := 'Ab Version 10g gibt es ein neues Package.'||cr;
   v_msg := v_msg ||'Es heisst UTL_MAIL ';
   v_msg := v_msg ||'und dient der Versendung von E-Mails.';
   UTL_MAIL.SEND
            (sender     => 'sender@muniqsoft.de',         
             recipients => 'info@muniqsoft.de',    
             subject    => 'Neues Package',                
             message    => v_msg);            
END;                                                         

                                                   

Attachments müssen in Form eines RAW- bzw. VARCHAR2-Parameters übergeben werden. Die Nachteile liegen auf der Hand:

  • Will man eine Datei anhängen, so muss man diese erst in eine passende Variable einlesen
  • Der Anhang ist auf 32K beschränkt, da dies in PL/SQL sowohl für RAW als auch für VARCHAR2 die Grenze ist

Neben dem Attachment können optional noch angegeben werden:

  • att_inline (Default: TRUE): Gibt an, ob das Attachment Teil des Mail-Bodies sein soll (TRUE) oder nicht (FALSE) 
  • att_mime_type (Default: 'application/octet')
  • att_filename (Default: NULL): Das ist der Dateiname, unter dem der Anhang erscheint

Wird nichts angegeben, so erscheint " .dat", daher ist eine Angabe empfehlenswert.

 

Beispiele:

CREATE DIRECTORY UTL_DIR AS 'C:\temp\For_Mail';
ECLARE
   v_file BFILE;
   v_buffer RAW(32767);
   v_len BINARY_INTEGER;
BEGIN
   v_file := BFILENAME('UTL_DIR', 'logo.gif');
   DBMS_LOB.FILEOPEN(v_file, DBMS_LOB.FILE_READONLY);
   v_len := DBMS_LOB.GETLENGTH(v_file);
   IF v_len <= 32767 THEN
      DBMS_LOB.READ(v_file, v_len, 1, v_buffer);
      UTL_MAIL.SEND_ATTACH_RAW(
                sender       => 'sender.de',
                recipients   => 'info@muniqsoft.de',
               subject      => 'Logo,
                message      => 'Versenden eines Bildes',
                attachment   => v_buffer,
                att_inline   => FALSE,
                att_filename => 'logo.gif' );
   END IF;
   DBMS_LOB.FILECLOSE(v_file);
END;
DECLARE
   v_file   UTL_FILE.FILE_TYPE;
   v_line   VARCHAR2(4000);
   v_buffer VARCHAR2(32767);
   cr         VARCHAR2(2000);
   v_bs     NUMBER;
   v_exists BOOLEAN;
   v_len    NUMBER;
BEGIN
   cr := CHR(13)||CHR(10);  
   UTL_FILE.FGETATTR('UTL_DIR', 'test.txt', v_exists, v_len, v_bs);
   IF v_exists AND v_len <= 32767 THEN
      v_file := UTL_FILE.FOPEN('UTL_DIR', 'test.txt', 'r');
      LOOP
         BEGIN
            UTL_FILE.GET_LINE(v_file, v_line); 
            v_buffer := v_buffer||cr||v_line;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               EXIT;
         END;
      END LOOP;
      UTL_FILE.FCLOSE(v_file);
      IF length(v_buffer) = v_len -2 THEN  --letztes CR ergänzen
         v_buffer := v_buffer ||cr;
      END IF;
      v_buffer := SUBSTR(v_buffer, 3); --erstes CR entfernen 
      UTL_MAIL.SEND_ATTACH_VARCHAR2
               (sender       => 'sender@muniqsoft.de',
                recipients   => 'recipient@muniqsoft.de',
                cc           => 'recipient2@muniqsoft.de',
                bcc          => 'recipient3@muniqsoft.de',
                subject      => 'UTL_MAIL Text',
                message      => 'Versenden von Text.',
                attachment   => v_buffer,
                att_inline   => FALSE,
                att_filename => 'test.txt' );
   ELSE
      DBMS_OUTPUT.PUT_LINE('Datei nicht vorhanden oder zu groß');
   END IF;
END;
/


Der Parameter att_inline hatte nicht auf alle getesteten Mail-Clients Einfluss. Bei Verwendung von Outlook war das Attachment nie Teil des Mail-Bodies, sondern immer ein "echter" Anhang.

Wenn Ihr Email-Server eine Authentifizierung benötigt, müssen Sie Ihren Email-Versand mit dem Package utl_smtp durchführen.