Gelegentlich steht man vor dem Problem, dass man auf Betriebssystem-Ebene Ascii-Dateien lesen oder schreiben soll oder muss. Dafür gibt es das Package UTL_FILE, das seit Version 7.3 zur Verfügung steht.
Was ist dabei zu beachten? Zunächst einmal, dass Oracle auf den gewünschten Verzeichnissen auf Betriebssystem-Ebene Lese- bzw. Schreibrechte haben muss. Dann müssen diese Verzeichnisse für die Benutzer freigegeben werden. In welcher Art dies geschieht, hängt von der Datenbank-Version ab:
Vor Version 9.2 geschieht dies über den Parameter UTL_FILE_DIR in der init<sid>.ora. Dabei gilt:
Prinzipiell kann auch der komplette Server freigegeben werden - unter Windows durch "*", unter Unix durch "." -, doch ist davon dringend abzuraten! UTL_FILE_DIR kann nicht im laufenden Betrieb geändert werden. Achten Sie bei Unix-Systemen auf Groß-/Kleinschreibung!
Ab Version 9.2 wird empfohlen, statt mit UTL_FILE_DIR mit DIRECTORY-Objekten zu arbeiten. Damit können dann explizit Lese- oder Schreibberechtigungen, eingeschränkt auf bestimmte Verzeichnisse, an Benutzer erteilt werden. Einzelheiten dazu finden Sie hier.
Leider ist beim Lesen einer Datei das Ende nicht abfragbar; wird versucht, darüber hinaus zu lesen, so wird die Exception NO_DATA_FOUND ausgelöst. Eine Exception wird auch ausgelöst, wenn das angegebene Directory-Objekt oder Verzeichnis nicht existiert bzw. (in Versionen vor 9.2) nicht in UTL_FILE_DIR angegeben wurde, oder wenn Oracle keine ausreichende Rechte darauf hat usw. Das Package enthält für solche Zwecke auch einige vordefinierte Exceptions. Werden diese nicht genutzt, so wird im Fehlerfall in älteren Versionen (verifiziert für 8.1.7) die Fehlermeldung ausgegeben:
ORA-06510: PL/SQL: Unbehandelte benutzerdefinierte Ausnahmebedingung
In Version 9.2 oder höher ist dieses Ärgernis beseitigt, und man erhält aussagekräftigere Fehlermeldungen.
Beim Öffnen der ASCII-Datei muss neben dem Verzeichnis und dem Namen auch angegeben werden, in welchem Modus sie geöffnet werden soll:
Gelesen wird mit GET_LINE, geschrieben wird mit PUT_LINE (bzw. PUT, NEW_LINE); weitere Einzelheiten finden Sie in der Oracle-Dokumentation.
Beispiel zum Schreiben:
UTL_FILE_DIR = c:\Temp
DECLARE
v_file UTL_FILE.FILE_TYPE;
BEGIN
v_file := UTL_FILE.FOPEN('C:\temp','test.txt', 'w');
UTL_FILE.PUT_LINE(v_file,' Überschrift');
UTL_FILE.NEW_LINE (v_file);
UTL_FILE.PUT_LINE(v_file,'Erste Zeile');
--....
UTL_FILE.FCLOSE(v_file);
EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('INVALID_PATH');
WHEN UTL_FILE.INVALID_MODE THEN
DBMS_OUTPUT.PUT_LINE('INVALID_MODE');
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
DBMS_OUTPUT.PUT_LINE('INVALID_filehandle');
WHEN UTL_FILE.INVALID_OPERATION THEN
DBMS_OUTPUT.PUT_LINE('INVALID_OPERATION');
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('WRITE_ERROR');
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE('READ_ERROR');
WHEN UTL_FILE.INTERNAL_ERROR THEN
DBMS_OUTPUT.PUT_LINE('INTERNAL_ERROR');
END;
/
Beispiel zum Lesen:
DECLARE
v_file UTL_FILE.FILE_TYPE;
v_line VARCHAR2(32000);
BEGIN
v_file := UTL_FILE.FOPEN('C:\temp','test.txt', 'r');
LOOP
BEGIN
UTL_FILE.GET_LINE(v_file, v_line);
DBMS_OUTPUT.PUT_LINE(SUBSTR(v_line,1,255));
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Fertig');
EXIT;
END;
END LOOP;
UTL_FILE.FCLOSE(v_file);
EXCEPTION
...
END;
/
Telefon:
089 6228 6789-0
Telefon (gültig bis Ende 2010):
089 679090-40
E-Mail:
› info@muniqsoft.de
Bitte nehmen Sie mich in den Verteiler der monatlichen Tipps & Tricks auf.