Logo Oracle Deutschland   Application Express Community
Tabellendaten mit APEX und der Data Pump exportieren
Erscheinungsmonat APEX-Version Datenbankversion
September 2014 alle alle

Wenn es darum geht, Datenbestände zwischen verschiedenen Oracle-Datenbanken zu übertragen, dann ist Export und Import das Mittel der Wahl. Mit Oracle10g wurde eine Alternative zu den "klassischen" Werkzeugen exp und imp geschaffen: Die Data Pump. Die wesentliche (und für diesen Tipp wichtige) Neuerung ist, dass die Data Pump serverbasiert arbeitet. Mit dem PL/SQL-Paket DBMS_DATAPUMP (Dokumentation hier) steht auch eine Programmierschnittstelle bereit, mit der Export- und Importvorgänge aus PL/SQL heraus angestoßen werden können.

In diesem Tipp zeigen wir Ihnen, wie Sie einen solchen Data Pump Export aus einer APEX-Anwendung heraus anstoßen und das Export-Dumpfile (welches ja auf dem Datenbankserver liegt) dennoch über eine APEX-Applikation herunterladen können. Abbildung 1 zeigt das Ergebnis.

Das Ziel: Data Pump Exports aus APEX starten und Dumpfiles herunterladen

Abbildung 1: Das Ziel: Data Pump Exports aus APEX starten und Dumpfiles herunterladen

Vorbereitungen

Obwohl die Data Pump in der Datenbank selbst arbeitet, wird jede Exportdatei dennoch ins Dateisystem des Datenbankservers geschrieben. Die Ausgabe der Exportdatei in ein BLOB ist nicht möglich. Schreibzugriffe in Verzeichnisse erfolgen in der Oracle-Datenbank mit Hilfe der Directory-Objekte. Sie haben nun zwei Möglichkeiten:

  • Ihr APEX Parsing Schema bekommt das Privileg CREATE ANY DIRECTORY. Anschließend erzeugen Sie die Directory-Objekte selbst wie folgt:
    create directory datapump_dir as '/tmp/'
    /
    
  • Der DBA richtet das Directory-Objekt ein und gibt dem APEX Parsing Schema sowohl das READ als auch das WRITE -Privileg.
    create directory datapump_dir as '/tmp/'
    /
    
    grant read on directory datapump_dir to {APEX Parsing Schema}
    /
    grant write on directory datapump_dir to {APEX Parsing Schema}
    /
    

Damit Die den folgenden Community-Tipp erfolgreich umsetzen können, brauchen Sie darüber hinaus das explizite CREATE TABLE Privileg (welches ein APEX Workspace-Schema aber meist ohnehin hat).

Export durchführen: PL/SQL

Im folgenden sind die Schritte beschrieben, die nötig sind, um mit PL/SQL einen Data Pump-Export durchzuführen. Hier wird davon ausgegangen, dass das Directory-Objekt vorliegt und für das Datenbankschema sowohl les- als auch schreibbar ist.

  1. Schritt 1: Data Pump Handle einrichten:
    Hier wird festgelegt, welche Operation nun durchgeführt wird ("EXPORT TABLE"). Der Parameter VERSION gibt an, für welche Oracle-Version das Dumpfile generiert wird. Hier sollte die Version eingestellt werden, in die das Dumpfile eingespielt werden soll.
      v_dp_handle := dbms_datapump.open(
        operation      => 'EXPORT',
        job_mode       => 'TABLE',
        version        => 10.0.0
      );
    
  2. Schritt 2: Directory-Objekt und Dateinamen einstellen:
      dbms_datapump.add_file(
        handle         => v_dp_handle,
        filename       => 'ExportFile.dmp',
        directory      => 'DATAPUMP_DIR'
      );
    
  3. Schritt 3: Festlegung, welche Tabellen exportiert werden sollen:
      dbms_datapump.metadata_filter(
        handle         => v_dp_handle,
        name           => 'NAME_EXPR',
        value          => '=''EMP'''
      );
    
  4. Schritt 4: Export (im Hintergrund) starten:
      dbms_datapump.start_job(
        handle        => v_dp_handle
      );
    
  5. Optional: Auf Beendigung des Jobs warten:
     dbms_datapump.wait_for_job(
        handle        => v_dp_handle,
        job_state     => v_dp_job_status -- OUT-Parameter (VARCHAR2)!!!
      );
    

Nachdem dieser Code durchgelaufen ist, befindet sich das Dumpfile im Dateisystem auf dem Datenbankserver. Dort ist es für den Anwender einer APEX-Anwendung natürlich nicht erreichbar - besser wäre, wenn es als BLOB in einer Tabelle wäre. Dann könnte man eine APEX-Anwendung erstellen, über die dann der Download möglich wäre. Als nächstes geht es also daran, die Inhalte der Exportdatei in eine Tabelle zu kopieren und die Datei dann aus dem Dateisystem zu löschen.

Exportdatei aus dem Dateisystem in eine Tabelle kopieren: PL/SQL

  1. Schritt 1: Variablen initialisieren:
    Es wird eine Variable vom Typ BLOB (für den Dateiinhalt) und eine vom Typ BFILE (als "Pointer" zur Exportdatei) benötigt. Mit der Funktion BFILENAME wird der Pointer auf die bereits generierte Exportdatei initialisiert. Damit die Inhalte der Datei in den BLOB kopiert werden können, wird dieser mit DBMS_LOB.CREATETEMPORARY als temporärer LOB initialisiert. werden soll.
    declare
      v_dump_content blob;
      v_dump_file    bfile;  
    
      v_dump_file := bfilename('DATAPUMP_DIR', 'ExportFile.dmp');
      dbms_lob.createtemporary(
        lob_loc  => v_dump_content,
        cache    => true,
        dur      => DBMS_LOB.CALL
      );
    
  2. Schritt 2: Dateiinhalte in temporären LOB kopieren:
    Das BFILE muss zunächt mit DBMS_LOB.OPEN explizit geöffnet werden, dann erfolgt das Kopieren mit der DBMS_LOB.LOADFROMFILE und schließlich wird das BFILE wieder geschlossen.
      dbms_lob.open(
        file_loc  => v_dump_file,   
        open_mode => DBMS_LOB.LOB_READONLY
      );
      dbms_lob.loadfromfile(
        dest_lob => v_dump_content,
        src_lob  => v_dump_file,
        amount   => DBMS_LOB.LOBMAXSIZE
      );
      dbms_lob.close(
        file_loc => v_dump_file
      );
    
  3. Schritt 3: Einfügen des BLOB in eine Tabelle:
    Das erfolgt mit einem ganz normalen SQL Insert-Kommando.
      insert into {table} (id, dump_content) values (1, v_dump_file);
                   
  4. Schritt 4: Aufräumen:
    Der temporäre LOB wurde in eine Tabelle eingefügt, daher kann er nun freigegeben werden. Außerdem wird die Exportdatei nun mit UTL_FILE.FREMOVE gelöscht - da die Inhalte sich nun in der Tabelle befinden, wird sie nicht mehr gebraucht.
      dbms_lob.freetemporary(
        lob_loc => v_dump_content
      );
    
      utl_file.fremove(
        location  => 'DATAPUMP_DIR', 
        filename  => 'ExportFile.dmp'
      );
    end;
    

Alles zusammenfügen: Eine einzige PL/SQL-Prozedur

Das SQL-Skript export-table.sql kombiniert alle Schritte in einer Prozedur und legt vorher die Tabelle für die Dumpfiles an. Lassen Sie es einfach in SQL*Plus oder im SQL Workshop laufen. Wenn Sie kein CREATE ANY DIRECTORY-Privileg haben, müssen Sie die CREATE DIRECTORY-Anweisung zu Beginn entfernen und sich das Directory-Objekt vom DBA einrichten lassen.

Eine APEX-Applikation, mit welcher die Exports angestoßen werden und die Dumpfiles aus dem Browser heruntergeladen werden können, ist nun ein Leichtes. Für den Datei-Download finden Sie Hinweise im Community Tipp "Dateien aus Application Express herunterladen". Eine kleine Beispielapplikation haben wir Ihnen als APEX-Exportdatei beigefügt. Dieser Anwendungsexport wurde auf einer APEX 3.2-Instanz erstellt (läuft aber auch in APEX 4.x problemlos) und enthält die Anwendung, die in Abbildung 1 oben dargestellt ist.

Zurück zur Community-Seite