CSV-Datei mit variablen Spalten in mySQL einlesen

In regelmäßigen Abständen muss eine CSV-Datei über ein von mir zu programmierendes Web-Interface in eine mySQL-Datenbank eingelesen werden. Beim Recherchieren habe ich bereits einige Lösungsvorschläge gefunden, die für meine Anwendung jedoch meines Erachtens nicht brauchbar sind.

Das Problem besteht nämlich darin, dass die Anzahl der Spalten und auch die Reihenfolge der Spalten variieren können. Das Skript müsste die erste Zeile auslesen: Hier stehen die Spaltenüberschriften, die immer gleich bleiben. Zwei Beispiele:

Import 1:

Name | Vorname | Plz | Ort | Geburtsdatum
Mustermann | Peter | 12345 ] Musterhausen | 10.01.1991

Import 2:

Ort | Vorname | Name | Plz
Musterdorf | Rita | Musterfrau | 54321

Die beiden Beispiele sind konstruiert und vereinfacht. In der späteren Anwendung stammen die Daten aus einem Anwendungsprogramm für Stunden- und Vertretungspläne, in dem der Benutzer die Anzahl und die Reihenfolge der Spalten für den Export flexibel definieren kann.

Wie muss ich die CSV-Datei auswerten und den mysql-Query zusammensetzen?

Hi

Ändert sich auch die Tabelle oder sind dort alle Spalten enthalten und die die nicht mit aufgeführt sind in der CSV datei werden in der Tabelle einfach leer gelassen?

Gruß Lamer

Ich hoffe, ich verstehe die Nachfrage(n) richtig:

  • die Struktur der mySQL-Tabelle wird nicht verändert
  • Spalten, die in der CSV-Datei, nicht jedoch in mySQL enthalten sind, werden ignoriert
  • Spalten, die in mySQL, nicht jedoch in der CSV-Datei enthalten sind, bleiben leer

Es gibt also eine feste Zuordnung Spaltenname mySQL Spaltenname CSV

Gruß
Marcus

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Das Problem besteht nämlich darin, dass die Anzahl der Spalten
und auch die Reihenfolge der Spalten variieren können. Das
Skript müsste die erste Zeile auslesen: Hier stehen die
Spaltenüberschriften, die immer gleich bleiben. Zwei
Beispiele:

Import 1:

Name | Vorname | Plz | Ort | Geburtsdatum
Mustermann | Peter | 12345 ] Musterhausen |
10.01.1991

Import 2:

Ort | Vorname | Name | Plz
Musterdorf | Rita | Musterfrau | 54321

Wie muss ich die CSV-Datei auswerten und den mysql-Query
zusammensetzen?

sinngemaess wie unten. sollte evtl. noch ueberarbeitet werden, dass das mapping nicht fuer jede csv-zeile getan werden muss:

$mysql\_cols = array('Name','Vorname','Geburtsdatum' ... );
$delim = " | ";


$lines = file("import");

/\*\*
\* macht aus "Ort | Vorname | Name | Plz" etwas wie:
\* ['Ort'=\>0,'Vorname'=\>1,'Name'=\>2 ...]
\*/
$csv\_names = array\_flip( explode( $delim,trim(array\_shift($lines))));

foreach ($lines as $line)
 {
 $line\_fields = explode( $delim,trim($line));
 $sql\_fields = array();

 /\*\*
 \* suche in der csv-zeile alle gueltigen mysql-spalten und erstelle fuer die treffer ein sql
 \*/
 foreach ($mysql\_cols as $c)
 {
 $csv\_colnum = $csv\_names[$c];
 if (isset($line\_fields[$csv\_colnum]))
 {
 /\*\*
 \* erzeugt ein " Vorname='Peter' "
 \*/
 $sql\_fields[] = $csv\_names[$c]."='".mysql\_escape\_string($line\_fields[$csv\_colnum])."'";
 }
 }

 if ($sql\_fields)
 {
 $sql = "insert into tabelle set ".implode(",",$sql\_fields);
 mysql\_query(...);
 }
 }

Vielen Dank für Deine Lösung, Jörg! Ich werde sie später gleich ausprobieren.

Ich habe das Skript erfolgreich einbauen können. Funktioniert prima!

Falls es jemand übernehmen wollte, empfehle ich jedoch folgende Änderung: Statt

/\*\* erzeugt ein " Vorname='Peter' " \*/
$sql\_fields[] = <u>$csv_names[$c]</u>."="...

verwende ich:

$sql\_fields[] = <u>$c</u>."="...

Marcus