MySQL Resultsets in Datei schreiben

Das Open Source Datenbanksystem MySQL bietet eine eingebaute Funktion INTO OUTFILE  zum Schreiben von Dateien. Mit dieser Funktion kann man z.B. Abfrageergebnisse direkt in eine strukturierte Ausgabedatei speichern.

Die Notation hierfür ist denkbar einfach. Man formuliert zunächst das gewünschte Select Statement und gibt anschliessend über die Funktion INTO OUTFILE den gewünschten Speicherpfad der Datei an. Wichtig hierbei sind natürlich die Schreibrechte auf das Zielverzeichnis. Da das Schreiben der Datei von der Datenbank ausgeführt wird, muss der Prozess unter der die Datanbank läuft auch entsprechende Schreibrechte auf das gewünschte Zielverzeichnis haben. Wichtig ist noch, dass MySQL die Aufgabedatei nicht einfach überschreibt. Wenn die Datei schon vorhanden ist, erhält man einen Fehler. Daher sollte man vielleicht bei der Vergabe des Dateinamen eine Variable einbeziehen, vielleicht Datum und Uhrzeit. Damit ist man auf der sichern Seite, dass die Funktion keinen Fehler wirft.

Neben dem Speicherort und den Namen der Ausgabedatei, kann man noch weitere Optionen zur Struktur der Ausgabedatei mitgeben:

SELECT a, b, c FROM tabelle 
INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

In diesem Fall wird über die Option FIELDS TERMINATED BY das Trennzeichen für jedes Feld des Abfrageergebnisses definiert. Mit der Option ENCLOSED BY gibt man noch zusätzlich jedes Feld einrahmen. Schlussendlich wird mit LINES TERMINATED BY noch das Zeilenende definiert. In diesem Beipiel wird ein Linefeed (Neue Zeile) angehängt, damit jede Zeile in eine neue Zeile geschrieben wird.

Mit dieser Funktion lassen sich einfache, aber auch komplexe Datenstrukturen in Ausgabedateien erzeugen.  Im Artikel Datenbankabfrage als XML Struktur ausgeben mit MySQL beschreibe ich wie man Abfragen als XML Struktur ausgibt und mit INTO OUTFILE läst sich die Struktur direkt in eine Datei schreiben. Ebenfalls eignet sich die Funktion im Zusammenhang mit Store Procedures. Dort kann man Ausgabedateien die perodisch erzeugt werden müssen, mit einer gespeicherten Prozedur direkt in der Datenbank ablegen.

Für das Problem mit dem Überschreiben einer Ausgabedatei, habe ich hier noch schnell eine kleine Prozedur geschrieben, die das aktuelle Datum und Uhrzeit in den Dateinamen der Ausgabedatei einbezieht. Somit kann es keine Probleme mit dem Überschreiben einer Ausgabedatei geben:

SET @outputpath := 'c:/test/';
SET @uniquer:= DATE_FORMAT(now(),'%Y-%m-%d_%H_%i_%s');
SET @fullOutputPath := CONCAT(@outputpath, @uniquer ,'-filename.csv');
 
set @q := concat("SELECT * INTO OUTFILE '",@fullOutputPath,
"' FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '\"'
FROM table");
 
prepare s from @q;
execute s;
deallocate prepare s;
http://www.agile-coding.net/mysql-resultsets-in-datei-schreiben/