# [ORACLE] Protokolle oder Berichte direkt aus der Datenbank



## Exceptionfault (26. Januar 2005)

Hi @ all,

ich stand kürzlich vor dem Problem, dass viele Jobs in der DB laufen und die Überwachung recht umständlich wird, zumal ich nicht unbedingt die Tablespaces mit "Log - Tabellen" zumüllen wollte.

Also war die Idee aus der Datenbank heraus Logfiles zu generieren. Es stelle sich heraus, dass das ganze eigentlich mehr als einfach ist und man das auch super für Berichte, einfache Exporte (CSV) und so Dinge verwenden kann.

Also, falls jemand ähnliche Ideen hat, hier mal ein kleines Tutorial vom UTL_FILE Package.

Zunächst muss der User SYS mal ein Verzeichnis definieren in dem wir wüten können:

```
CONNECT sys/oracle as sysdba
CREATE OR REPLACE DIRECTORY output_dir AS 'd:\';
```

Normalerweise kommt nun noch eine Vergabe von Rechten an den entsprechenden User. Da meine Prozeduren als SYS liefen, war das nicht nötig.

Der nächste Codeblock macht folgendes:

Wir öffnen einen Cursor und lesen alle Benutzernamen aus der Datenbank. 
Mit einer Schleife laufen wir über jeden einzelnen Datensatz.
Für jeden Benutzer wird eine Zeile in die Datei "d:\users.txt" geschrieben.
Am Ende wird alles wieder geschlossen.


```
DECLARE
	fp		        UTL_FILE.FILE_TYPE; 
	uname			DBA_USERS.USERNAME%TYPE;
	CURSOR c1 IS 
		SELECT USERNAME FROM DBA_USERS;
BEGIN

	fp := UTL_FILE.FOPEN (
			location  	=> 'OUTPUT_DIR',
			filename  	=> 'users.txt',
			open_mode 	=> 'w',
			max_linesize => 32767
	);

	OPEN c1;
	
	LOOP
		FETCH c1 INTO uname;
		EXIT WHEN c1%NOTFOUND;
	
		UTL_FILE.PUT_LINE (
			file      => fp,
			buffer    => uname,
			autoflush => true
		);
		
	END LOOP;
	
	CLOSE c1;
	
	UTL_FILE.FFLUSH ( fp );
	UTL_FILE.FCLOSE( fp ); 
	UTL_FILE.FCLOSE_ALL;
  
END;
/
```

Das ganze kann man z.B. auch als Prozedur in die DB legen, der man einfach nur noch den Filenamen und den Logtext übergeben muss und fertig ist der Logger!

Noch ein paar kleine Anmerkungen:
Ich rufe am Ende 2x FCLOSE bzw. FCLOSE_ALL auf. Ich hatte beim Test das Problem, dass erst nach dieser Konstellation das Textfile Lesbar wurde ohne die Session zu beenden. Auch ein COMMIT half nicht. Oracle hatte immer noch einen Pointer auf das File. 
Ich geben für den Usernamen keinen expliziten Datentype an sondern DBA_USERS.USERNAME%TYPE. Das ist so state of the Art, denn es kann mir somit egal sein, wie groß Oracle das Feld definiert hat, meine Variable passt immer. 

Noch Fragen ? Nur zu!


----------

