E-Mails versenden mit UTL MAIL (10g)

01.
Januar
2006
Veröffentlicht von: Hildegard Asenbauer

Mit Version 10g hat Oracle UTL_MAIL herausgebracht, ein neues Package, das wesentlich
mehr Anwendungskomfort bietet. Für die Versionen 10.1.x ist jedoch eine ganze Reihe von
Bugs beschrieben, die spätestens in Version 10.2. behoben wurden, so dass UTL_MAIL erst
ab dieser Version zu empfehlen ist.

Mit Version 10g hat Oracle UTL_MAIL herausgebracht, ein neues Package, das wesentlich
mehr Anwendungskomfort bietet. Für die Versionen 10.1.x ist jedoch eine ganze Reihe von

Bugs beschrieben, die spätestens in Version 10.2. behoben wurden, so dass UTL_MAIL erst

ab dieser Version zu empfehlen ist.

Vorbereitungen

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

  1. Installation:
    Aus Sicherheitsgründen ist dieses Package nicht standardmäßig installiert. Zur Installation müssen als SYS folgende Skripte aufgerufen werden:
    •    <ORACLE_HOME>\RDBMS\ADMIN\utlmail.sql: legt den Package Header an und ein Public Synonym
    •    <ORACLE_HOME>\RDBMS\ADMIN\prvtmail.plb: legt den Package Body an 

  2. 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.

  3. EXECUTE-Recht vergeben

Beispiel:

SQL> CONN / AS SYSDBA
SQL> @?\rdbms\admin\utlmail.sql
Package wurde erstellt.
Synonym wurde erstellt.
SQL> @?\rdbms\admin\prvtmail.plb
Package Body wurde erstellt.
Keine Fehler.
SQL> ALTER SYSTEM SET SMTP_OUT_SERVER='myserver' SCOPE=SPFILE;
...
SQL> GRANT EXECUTE ON UTL_MAIL TO SYSTEM;

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.

Alle Beispiele wurden auf Windows-Systemen und Oracle 10.2.0.1.0 getestet. Bei Binärdateien war das Attachment exakt identisch mit dem Original, bei Textdateien (oder auch direkt übergebenen Strings) wurde am Dateibeginn stets ein Zeilenumbruch eingefügt. Dieser Bug ist bisher in Metalink nicht beschrieben.

Ein weiterer, für Version 10.2.0.1 beschriebener Bug (Bug Nr.: 4466305, Note:4466305.8) wurde verifiziert: Wenn "subject" eine gewisse Länge überschreitet - laut Beschreibung 65 Zeichen, in unseren Händen bereits ab 42 Zeichen - wird die Mail praktisch unleserlich, da im Mail-Body diverse Steuerzeichen (und der Anhang) erscheinen. Außerdem wird der Betreff ab dieser Position abgeschnitten. Ab Version 10.2.0.2 soll auch dieser Fehler behoben sein.

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

Ergänzungen:

Für die Versionen 10.2.0.3 und 11g konnte verifiziert werden, dass Bug Nr. 4466305 behoben ist. 

Auch in 11g fand sich bei der Versendung von Textfiles zu Beginn noch immer ein Zeilenumbruch

DBA PL/SQL Mails

Jede Menge Know-how für Sie!

In unserer Know-How Datenbank finden Sie mehr als 300 ausführliche Beiträge zu den Oracle-Themen wie DBA, SQL, PL/SQL, APEX und vielem mehr.
Hier erhalten Sie Antworten auf Ihre Fragen.