Logo Oracle Deutschland   Application Express Community
Dateien mit APEX in Datenbanktabellen hochladen: Möglichkeiten ...
Erscheinungsmonat APEX-Version Datenbankversion
Juni 2015 ab 5.0 ab 11.1

Dass Dateien mit einer APEX-Anwendundung in Tabellen hochgeladen werden müssen, ist eine gängige Anforderung. Und seit den ersten Versionen von APEX hat sich hier auch eine ganze Menge getan - speziell in APEX 5.0 wurden nochmals Neuerungen beim Datei-Upload eingeführt. Während man früher den Prozess komplett "von Hand" programmieren musste, bietet APEX heute fertige Komponenten an - einfache Fälle lassen sich damit ohne PL/SQL-Programmierung lösen. In diesem Tipp stellen wir beide Varianten vor - neben der einfachen auch die "manuelle Programmierung"; denn für "ausgefallene" Anforderungen wird diese immer noch gebraucht ...

Vorbereitungen

Zunächst wird eine Tabelle benötigt. Neben der Spalte vom Typ BLOB für den Dateiinhalt werden noch weitere für die "Metadaten" der Datei benötigt - am wichtigsten ist eine Spalte für den Dateinamen (DATEINAME) und eine für den Dateityp (MIMETYPE). Legen Sie die Tabelle also wie folgt an.

create table tab_dateien(
  id               number(10),
  dateiname        varchar2(200),
  mimetype         varchar2(100),
  dateiinhalt      blob,
  hochgeladen_am   date not null,
  letzte_aenderung date not null,
  constraint pk_dateien primary key (id)
)
/

create sequence seq_dateien
/

create or replace trigger tr_bui_dateien
before insert or update on tab_dateien
for each row
begin
  if inserting then 
    select seq_dateien.nextval into :new.id from dual; 
    :new.hochgeladen_am := sysdate;
    :new.letzte_aenderung := sysdate;
  end if;
  if updating then
    :new.letzte_aenderung := sysdate;
  end if;
end;
/

Datei-Upload mit APEX-Komponenten: ohne Programmierung

Erzeugen Sie dann ein Formular zum Hochladen. Für diese Tabelle wird tatsächlich nur ein Formularfeld benötigt. Erstellen Sie also eine neue, Anwendungsseite mit einer HTML Region hinzu. Dieser Region Fügen Sie dann ein neues Formularelement zum Hochladen einer Datei (P2_DATEI) hinzu (Abbildung 1).

Formularelement vom Typ "Datei hochladen"

Abbildung 1: Formularelement vom Typ "Datei hochladen"

Klicken Sie das erzeugte Element dann an und navigieren Sie im Property-Editor rechts zum Abschnitt Settings (Abbildung 2).

Einstellungen zum Element vom Typ "Datei hochladen"

Abbildung 2: Einstellungen zum Element vom Typ "Datei hochladen"

  • Als Storage Type wählen Sie BLOB column specified in Item Source attribute aus
  • Als MIME type Column geben Sie MIMETYPE an.
  • Als Filename Column geben Sie DATEINAME an.
  • Die Characterset Column können Sie leer lassen.
  • Die BLOB Last Updated Column ist LETZTE_AENDERUNG.
  • Und Display Download Link stellen Sie auf No.

Navigieren Sie dann weiter zum Bereich Quelle (Source). Stellen Sie dort den Source Type auf Database Column (achten Sie darauf, dass Source Used auf "Always, replacing any ..." steht) und geben Sie DATEIINHALT als Database Column Name an. Speichern Sie die Änderungen dann mit einem Klick auf den Save-Button im Page Designer oben rechts ab.

Das neue Element hat die Quelle "Database Column"

Abbildung 3: Das neue Element hat die Quelle "Database Column"

Anschließend brauchen Sie noch ein verstecktes Element P2_ID und einen Button zum Absenden. Ziehen Sie diese wieder aus der Palette unten auf Ihre Seite und achten Sie bei den Einstellungen darauf, dass bei Klick auf den Button ein Submit Page stattfindet. Legen Sie außerdem SQL INSERT Action als Database Action fest.

Schaltfläche zum Absenden einrichten

Abbildung 4: Schaltfläche zum Absenden einrichten

Im Page Designer sollte Ihre Seite nun in etwa wie in Abbildung 5 aussehen.

Seitendarstellung im Page Designer mit Filebrowse-Element und Upload-Button

Abbildung 5: Seitendarstellung im Page Designer mit Filebrowse-Element und Upload-Button

Wenn Sie die Seite nun starten, sieht soweit alles vollständig aus; Sie können auch schon eine Datei auswählen und hochladen; es passiert nur nichts: Ihre Tabelle bleibt (noch) leer. Navigieren Sie also zurück zum Page Designer und klicken Sie im Strukturbaum rechts auf den Reiter für die Prozesse (der dritte von links). Im Menüpunkt Processes klicken Sie die rechte Maustaste, um einen neuen Prozess hinzuzufügen (Abbildung 6).

Einen neuen Prozess anlegen

Abbildung 6: Einen neuen Prozess anlegen

Geben Sie dem Prozess unter Identification einen Namen und wählen Sie Automatic Row Processing als Type aus (Abbildung 7).

Prozesstyp "Automatic Row Processing" auswählen

Abbildung 7: Prozesstyp festlegen

Im Bereich Settings tragen Sie TAB_DATEIEN als Table Name ein und legen Sie fest, dass ID die Primary Key Column ist und dass P2_ID das Primary Key Element ist. Klicken Sie SQL Insert Action bei den Supported Operations an und speichern Sie die Änderungen dann mit dem Save-Button des Page Designers oben rechts ab.

Einstellungen zur Tabelle und zum Primärschlüssel

Abbildung 8: Einstellungen zur Tabelle und zum Primärschlüssel

Nun ist alles fertig. Wenn Sie die Seite nun starten, eine Datei hochladen und anschließend (per SQL Workshop) in Ihre Tabelle schauen, sehen Sie, wie die Datei hochgeladen wurde (ein zusätzlicher SQL-Bericht auf der Seite, wie in Abbildung 9, tut es natürlich auch).

Die Anwendungsseite zum Datei-Upload ist fertig

Abbildung 9: Die Anwendungsseite zum Datei-Upload ist fertig

Mehr Kontrolle: Dateien hochladen mit PL/SQL

Die bis hierhin beschriebene Vorgehensweise ist sehr einfach in der Umsetzung und kann sogar mit "normalen" Formularfeldern kombiniert werden. Wenn Sie ein Formular auf eine Tabelle erzeugen, wird das Dateiauswahlfeld automatisch für die BLOB-Spalte generiert. Das Verfahren erlaubt jedoch keine Eingriffe in das SQL Insert-Kommando, mit dem die Datei tatsächlich in die Tabelle abgelegt wird. Wenn hier neben dem reinen Speichern zusätzliche Logik gefordert ist, stößt der automatisierte Prozess an seine Grenzen - eigener PL/SQL-Code muss eingehängt werden. Als nächstes stellen wir also vor, wie Sie den Datei-Upload "von Hand" programmieren.

Fügen Sie Ihrer Anwendung noch eine leere Seite mit einer HTML-Region hinzu. Legen Sie wiederum ein Element vom Typ Datei hochladen (P2_DATEI) an, bei den Einstellungen (Settings) gehen Sie jedoch anders vor. Wie in Abbildung 10 dargestellt, wählen Sie Tabelle APEX_APPLICATION_TEMP_FILES als Storage Type aus. Purge File At stellen Sie auf End Of Request.

Formularelement "Datei hochladen" mit "APEX_APPLICATION_TEMP_FILES" als "Storage Type"

Abbildung 10: Formularelement "Datei hochladen" mit "APEX_APPLICATION_TEMP_FILES" als "Storage Type"

Das bedeutet, dass die Datei nicht in Ihre eigene, sondern in die APEX-Systemtabelle APEX_APPLICATION_TEMP_FILES gespeichert wird. Mit eigenem PL/SQL-Code können Sie diese dort herausholen, bearbeiten und in ihre eigene Tabelle speichern.

Dies ist eines der neuen Features in APEX 5.0 - in früheren Versionen konnte man hier die Tabelle WWV_FLOW_FILES angeben und ein automatisches Purge gab es nicht. APEX 5.0 ordnet den Umgang mit hochgeladenen Dateien neu: Alle per Filebrowse-Element hochgeladenen Dateien landen in der Tabelle APEX_APPLICATION_TEMP_FILES - und APEX löscht diese Dateien automatisch - je nach der Einstellung Purge File At.

Ist Purge File At auf End of Request gestellt, so können Sie davon ausgehen, dass die Datei aus APEX_APPLICATION_TEMP_FILES gelöscht ist, sobald Sie nach Ausführung Ihres Prozesses die neue APEX-Seite sehen - in diesem Community-Beispiel wird sie ja in die Tabelle TAB_DATEIEN übernommen. Möchten Sie die Datei noch etwas länger behalten, um später noch weitere Operationen damit machen zu können, so stellen Sie auf End Of Session. Prinzipiell sollten Sie End Of Request stets bevorzugen.

Die statischen Dateien, die man als Entwickler im Bereich der Gemeinsamen Komponenten hochlädt, sind ab APEX 5.0 nicht mehr mit den per Filebrowse-Element hochgeladenen Dateien vermischt - sie befinden sich in eigenen Tabellen. Alles in allem ist APEX 5.0 im Bereich der Dateien wesentlich strukturierter als früher.

Legen Sie danach wie vorhin eine Schaltfläche zum Absenden der Seite an; das versteckte Element P2_ID brauchen Sie nicht unbedingt. Danach geht es an das Einrichten des Prozesses. Erstellen Sie einen neuen Prozess (Abbildung 6) und wählen Sie PL/SQL als Prozesstyp aus (Abbildung 11).

Prozesstyp "PL/SQL" wählen

Abbildung 11: Prozesstyp "PL/SQL" wählen

Hinterlegen Sie folgenden PL/SQL-Code.

declare
  v_datei     blob;
  v_dateiname tab_dateien.dateiname%type;
  v_mimetype  tab_dateien.mimetype%type;
begin
  begin
    select
      blob_content,
      filename,
      mime_type
    into v_datei, v_dateiname, v_mimetype
    from apex_application_temp_files 
    where name = :P2_DATEI;
  
    -- Der Blob in V_DATEI kann hier weiter verarbeitet werden:
    -- * Umwandeln in ein CLOB
    -- * Bildbearbeitung mit ORDIMAGE-Methoden
    -- * ...

    insert into tab_dateien (dateiname, mimetype, dateiinhalt)
    values (v_dateiname, v_mimetype, v_datei);
 
    -- Die Datei muss nicht aus APEX_APPLICATION_TEMP_FILES gelöscht werden;
    -- das passiert automatisch!
  exception
    when NO_DATA_FOUND then null;
  end;
end;

Da das Speichern in die Tabelle hier von ihrem eigenen PL/SQL-Code erledigt wird, können Sie hier beliebige Dinge tun: Ob es darum geht, parallel in eine zweite Tabelle zu schreiben, den BLOB in einen CLOB umzuwandeln oder ein Bild mit den Prozeduren und Funktionen des Paketes ORDIMAGE zu bearbeiten - alles kein Problem.

Fazit

Es ist sehr einfach, Dateien mit APEX in eigene Tabellen hochzuladen. In einfach gelagerten Fällen kommt man komplett ohne Programmierung aus; die APEX-Standardkomponenten erledigen die ganze Arbeit. Wie immer (und das ist das Gute) ist APEX bei komplexeren Anforderungen völlig offen - das Speichern kann auch mit eigenem Code realisiert werden. Und die letztere Option öffnet eine APEX-Anwendung auch für ausgefallene Dinge ...

Zurück zur Community-Seite