
Das IT-Magazin der ORDIX AG mit Fachbeiträgen zu Datenbanken, Unix und Java/XML.
Die Ablage von unstrukturierbaren Daten wie Text, Video, Bildern oder Sound kann in Oracle in LOB-Datentypen (Large Objects) vorgenommen werden. Hierbei kann es sich sowohl um binäre als auch um charakter-basierte Daten handeln. Diese Daten können in der Datenbank gehalten werden (BLOB, CLOB und NCLOB) oder auch im Filesystem (BFILE).
Bei den BFILE-Datentypen werden Dateipfad und -name in der Datenbank abgelegt. Bei allen Datentypen können bis 4 GB Daten gespeichert werden. Leider können LOBs nicht mittels SQL bearbeitet werden.
Es gibt aber das Package „DBMS_LOB“, das den Zugriff und die Verwaltung von LOBs unterstützt. Dieses Package wird im Folgenden vorgestellt. Die Suche innerhalb von LOBs wird von der InterMedia Option unterstützt. Darauf geht dieser Artikel jedoch nicht näher ein.
| Name | Beschreibung | BFILE | BLOB/ CLOB/ NCLOB |
| APPEND | Hängt den Inhalt eines LOBs an ein LOB an | x | |
| COMPARE | Vergleicht zwei LOBs oder Teile von diesen miteinander |
x | x |
| COPY | Kopiert den Inhalt eines LOBs in ein LOB | x | |
| ERASE | Entfernt (teilweise) den Inhalt eines internen LOBs, innerhalb eines LOBs werden Füllzeichen gesetzt |
x | |
| FILECLOSE | Schließt ein geöffnetes BFILE | x | |
| FILECLOSEALL | Schließt alle zur Zeit geöffneten LOBs vom Typ BFILE | x | |
| FILEEXISTS | Prüft, ob eine Datei vorhanden ist | x | |
| FILEGETNAME | Gibt den Dateinamen und Alias-Namen zu einem File-Locator zurück | x | |
| FILEOPEN | Öffnet eine Datei (BFILE) zum Lesen | x | |
| FILEISOPEN | Prüft, ob eine Datei geöffnet ist | x | |
| GETLENGTH | Die Länge eines LOBs in Byte bei BFILE und BLOBs, in Characters bei CLOBs und NCLOBs | x | x |
| INSTR | Gibt die n-te Position eines Teil-LOBs innerhalb eines LOBs zurück | x | x |
| LOADFROMFILE | Liest eine BFILE in ein LOB ein | x | x |
| READ | unterstützt das stückweise Auslesen eines LOBs | x | x |
| SUBSTR | Schneidet aus einem LOB einen Teil aus | x | x |
| TRIM | Schneidet ein LOB auf eine neue Länge zu | x | |
| WRITE | Schreibt eine gegebene Anzahl von Bytes oder Charakters in ein LOB an eine vorgegebene Position |
x | |
| Abb.1: Übersicht über die im Package enthaltenen Funktionen und Prozeduren. Sie gibt die Verwendbarkeit bezüglich der Sub-Typen an. | |||
Eine Einschränkung gibt es bei der Nutzung des Package: DBMS_LOB kann nur von der Server-Seite genutzt werden, nicht vom Client aus.
In den meisten Fällen liegen die Daten anhand von Dateien im Filesystem vor. Hierzu ist die Betrachtung des BFILE-Datentyps nützlich.
Der BFILE-Datentyp wird benutzt, um „large binary objects“ bis zu einer Größe von vier Gigabyte außerhalb der Datenbank zu halten. Zur Verwaltung benutzt man einen Locator. Dieser zeigt auf einen Directory-Alias und einen Dateinamen. Dazu sind die folgenden Voraussetzungen notwendig:
Die einzulesenden Daten sollen in eine Tabelle mit entsprechender Struktur eingeladen werden.
Beispiel:
create table lob_documents (
doc_id NUMBER(10,0) PRIMARY KEY
docname VARCHAR2(200),
doc CLOB,
timestamp DATE);
CREATE OR REPLACE PROCEDURE lobfile_einladen
(dir varchar2,name varchar2:=NULL)
is
dasbfile BFILE;
dasclob CLOB;
docname VARCHAR2(200):=nvl(name,’standard.txt’);
b_existiert_datei BOOLEAN;
BEGIN
INSERT INTO lob_documents(doc_id, docname, doc, timestamp)
VALUES
-- empty_clob/empty_blob initialisieren die LOB-Spalte
(seq_lob.nextval, docname,empty_clob(),sysdate)
-- Die Returning-Klausel erwartet einen gueltigen Locator
returning doc into dasclob;
-- BFILE-Locator wird auf eine Datei im Filesystem gesetzt
dasbfile:=bfilename(dir,name);
b_existiert_datei:= DBMS_LOB.FILEEXISTS(dasbfile)=1;
IF b_existiert_datei
THEN
-- die Datei wird zum Lesen geöffnet
DBMS_LOB.FILEOPEN(dasbfile);
-- die Datei wird in dasclob gelesen,
DBMS_LOB.LOADFROMFILE(dest_lob=>dasclob,src_lob=>dasbfile,
-- getlength ermittelt die Laenge der Datei
amount=>DBMS_LOB.GETLENGTH(dasbfile));
IF DBMS_LOB.FILEISOPEN(dasbfile)=1 -- Funktion liefert kein BOOLEAN!
THEN
DBMS_LOB.FILECLOSE(dasbfile);
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
-- Falls noch irgendein Locator offen ist, so wird er jetzt geschlossen
DBMS_LOB.FILECLOSEALL;
END;
/
ORDIX auf der CeBIT vom 13.-20.03.2002 in Hannover Besuchen Sie uns auf dem "Oracle Partner Stand der DOAG" in Halle 4. |
| Abb. 2: Beispieldatei "cebit.txt". |
Aufruf: execute lobfile_einladen(‘LOBFILES‘,‘cebit.txt‘); Die beigefügte Datei cebit.txt, Abb. 2, ist eine Text-Datei. Bilder wären gegebenenfalls über zusätzliche Spalten analog in die Datenbank abzulegen.
Für den Vergleich von zwei LOB-Feldern mit demselben Typ dient der Aufruf von dbms_lob.compare. Im folgenden Bespiel wird überprüft, ob ein Dokument bereits in der Tabelle lob_document enthalten ist.
CREATE OR REPLACE FUNCTION mein_vergleich(p_lob CLOB) RETURN BOOLEAN
IS
CURSOR c_clob IS
SELECT * FROM lob_documents;
BEGIN
FOR pc IN c_clob LOOP
IF DBMS_LOB.COMPARE(p_lob, pc.doc)=0
THEN RETURN TRUE; -- Dokument wurde gefunden
END IF;
END LOOP;
RETURN FALSE;
END;
/
Anhand der nächsten Funktion wird gezeigt, wie in einem Dokument ein Begriff gesucht werden kann und das folgende Wort ausgegeben werden kann.
CREATE OR REPLACE FUNCTION finde_und_hole_text (p_lob CLOB, p_suche VARCHAR2, p_nte INTEGER DEFAULT 1) RETURN VARCHAR2 IS v_position INTEGER; v_position_bis INTEGER; v_wort VARCHAR2(200); BEGIN v_position:=DBMS_LOB.INSTR(p_lob, p_suche, 1, p_nte); IF v_position> 0 -- gefunden THEN v_position:=DBMS_LOB.INSTR(p_lob, ‘ ‘, v_position); -- Ende Suchbegriff, nächstes Blank v_position_bis:=DBMS_LOB.INSTR(p_lob, ‘ ‘, v_position+1); --Ende nächstes Wort durch nächstes Blank IF v_position > 0 and v_position_bis>v_position THEN v_wort:=DBMS_LOB.SUBSTR(p_lob, v_position_bis-v_position,v_position); RETURN v_wort; ELSE RETURN NULL; END IF; ELSE RETURN NULL; END IF; RETURN NULL; EXCEPTION WHEN OTHERS THEN RETURN NULL; END; /
DECLARE CURSOR c_clob IS SELECT * FROM lob_documents; BEGIN FOR pc IN c_clob LOOP DBMS_OUTPUT.PUT_LINE(NVL (finde_und_hole_text(pc.doc,‘Referent‘,1),‘Nichts gefunden‘)); END LOOP; END; / |
| Abb. 3: Dieser Aufruf findet in jedem Dokument der Tabelle „lob_documents“ das erste Vorkommen des Wortes „Referent“ und gibt das darauffolgende Wort aus. |
Die Prozedur DBMS_LOB.WRITE ermöglicht das Schreiben von Daten (sowohl binär als auch charakter-basiert) in ein LOB.
DECLARE
CURSOR c_clob IS
SELECT * FROM lob_documents
FOR UPDATE;
BEGIN
FOR pc IN c_clob LOOP
DBMS_LOB.WRITE(pc.doc,
length(‘COPYRIGHT ORDIX AG ‘|| SYSDATE),
DBMS_LOB.GETLENGTH(pc.doc), ‘ ORDIX AG ‘|| SYSDATE);
END LOOP;
END;
/
|
| Abb. 4: In diesem Aufruf wird an das Ende des LOBs ein Text angehängt. Dazu muss der Datensatz zum Update gesperrt sein. |
Sollen die Inhalte zweier LOBs konkateniert werden, so dient dazu die Prozedur DBMS_LOB.APPEND. Zur Benutzung der weiteren Funktionalitäten dieses Package wird auf die Dokumentation verwiesen.
In der nächsten ORDIX News Ausgabe untersuchen wir das Package DBMS_DEBUG.
Beate Künneke (info@ordix.de).