CSV -> Array -> SQL
DanielE
- php
Hallo,
ich lese mit fgetcsv eine CSV Datei in ein Array und schreibe dieses anschließend in eine SQL db. Meine CSV Datei hat 7 Spalten (0 - 7). Was ich nicht navollziehen kann ist, wenn ich im SQL nur die ersten 3 Spalten übergebe klappt das Script wunderbar. Nehme ich alle 7 Spalten bekomme ich einen Undefined offset. In meiner CSV sind nicht alle Zeilen über alle Spalten gefüllt. Es gibt leere Zellen, auch in den ersten Spalten die immer korrekt ausgeführt werden.
Warum schmeißt mein Schript einen Fehler wenn ich das Array um die ganze Länge meiner CSV ergänze? Hängt es damit zusammen das in den Spalten 4-7 fast alle Zellen leer sind? Ich kann mir das nicht erklären.
Hier das Script wie es im Moment aussieht mit dem Array bis Spalte 4.
----------------------------------------------------------
$handle = fopen ("uploads/haendler_deutschland.csv","r");
while ($data = fgetcsv ($handle, 1000, ";"))
{
$query = "INSERT INTO brd(id
, name
, strasse
, plz
) VALUES('', '".$data[1]."', '".$data[2]."', '".$data[3]."')";
$result = mysql_query($query) or die("Invalid query: " . mysql_error().__LINE__.__FILE__);
$row++;
}
fclose ($handle);
--------------------------------------------------------
Bin dankbar für jeden Tipp,
Daniel
Ich grüsse den Cosmos,
Hier das Script wie es im Moment aussieht mit dem Array bis Spalte
Viel spannender wäre die CSV-Datei.
Hast du alle Kommas drin, oder nur einen String
eins,zwei,drei,vier
ohne die restlichen Trenner?
Ansonsten solltest du mal nachlesen, wie fgetcsv() das Array erzeugt, wenn keine Werte enthalten sind.
Möge das "Self" mit euch sein
Hallo
Viel spannender wäre die CSV-Datei.
Hast du alle Kommas drin, oder nur einen Stringeins,zwei,drei,vier
ohne die restlichen Trenner?#
Tatsächlich! Ich habe die CSV Datei nun mal im TextEditor bekuckt und in allen Zeilen die nicht bis zu Ende ausgefüllt sind, fehlen die ; für die leeren Spalten. Sowas! Kann man das dem Excel beim speichern irgendwie beibringen das er das ordentlich macht?
fgetcsv habe ich nachgelesen und es heißt dort: " Eine leere Zeile der CSV-Datei wird als Array mit einem Feld das den Wert NULL hält zurückgegeben. Sie wird nicht als Fehler behandelt." Sollte also eigentlich kein Problem sein.
Gruß Daniel
Hi!
Tatsächlich! Ich habe die CSV Datei nun mal im TextEditor bekuckt und in allen Zeilen die nicht bis zu Ende ausgefüllt sind, fehlen die ; für die leeren Spalten. Sowas! Kann man das dem Excel beim speichern irgendwie beibringen das er das ordentlich macht?
Am einfachsten wohl, indem man der Tabelle eine Kopfzeile mit Ueberschriften verpasst.
Hallo,
Am einfachsten wohl, indem man der Tabelle eine Kopfzeile mit Ueberschriften verpasst.
Habe ich.
Das komische ist ja das meine CVS Datei komplett und richtig gelesen und in die db geschrieben wird. Nur das während dieses Vorgangs diese Fehlermeldung für jede Zeile auftaucht.
Notice: Undefined offset: 6 in /homepages/18/d15411788/htdocs/admin/dealer.csv.php on line 89
Notice: Undefined offset: 7 in /homepages/18/d15411788/htdocs/admin/dealer.csv.php on line 89
Nehme ich die letzten beiden Spalten raus, verschiebt sich der Fehler um 2 Spalten nach vorn.
Gruß Daniel
Schmeiss doch mal den inhalt (nicht den kompletten) deiner CSV und deinen Code huebsch formatiert hier rein. Dazu nochmal die Fehlermeldung die dieser code generiert.
Hallo,
habe gerade festgestellt das wenn ich im Excel am Ende noch eine komplett ausgefüllte Spalte setze dann werden in der CVS Datei alle ; geschrieben und dann klappt der Import mit meinem Script fehlerfrei.
Für mich bleibt nur noch die Frage wieso Excel nicht gleich für leere Zellen ein ;; schreibt. Da werde ich mich wohl mal in diversen Office Foren schlau machen müssen.
vielen Dank ersteinmal ihr habt mich auf die richtige Spur gebracht.
Daniel
Das war mit eine Headerzeile gemeint. Normalerweise sorgt diese komplette Zeile (mit spaltenueberschriften) dafuer dass alles darunter (bei dir darueber) auch angezeigt wird. Eben auch, wenn es leer ist. Sonst wurden die spalten ja auch verrutschen, was bei Dir quasi passiert ist.
Das war mit eine Headerzeile gemeint. Normalerweise sorgt diese komplette Zeile (mit spaltenueberschriften) dafuer dass alles darunter (bei dir darueber) auch angezeigt wird. Eben auch, wenn es leer ist. Sonst wurden die spalten ja auch verrutschen, was bei Dir quasi passiert ist.
Ja das habe ich schon richtig verstanden und wie gesagt ich habe ja als erstes einen "Überschriftszeile". Trotzdem werden Zeile für Zeile nur soviele Zellen im Sinne von ;; geschrieben wie Inhalte vorhanden sind. Ich habe nun eine neue Spalte ans Ende vom Dokument gesetzt (mit . als Inhalt für alle Zeilen ) und dann werden alle Zellen, egal ob leer oder nicht, bis zum Ende mitgenommen.
Danke für die Tipps
Ich grüsse den Cosmos,
Für mich bleibt nur noch die Frage wieso Excel nicht gleich für leere Zellen ein ;; schreibt.
Weil sich MS grundsätzlich nicht an Standards hält, und an Quasistandards sowieso nicht, wenn sie nicht aus dem eigenen Haus kommen
Möge das "Self" mit euch sein
$handle = fopen ("uploads/haendler_deutschland.csv","r");
while ($data = fgetcsv ($handle, 1000, ";"))
{
$query = "INSERT INTO brd(id
,name
,strasse
,plz
) VALUES('', '".$data[1]."', '".$data[2]."', '".$data[3]."')";
$result = mysql_query($query) or die("Invalid query: " . mysql_error().__LINE__.__FILE__);
$row++;
}
fclose ($handle);
1.) Wie lautet die Fehlermeldung genau?
2.) Die Schleife ist uncool und belastet den Datenserver unnötig.
3.) Lade das CSV und prüfe die Daten per Schleife auf Integrität, also ob mandatorische numerische Inhalte auch numerisch sind und ob der Dezimaltrenner stimmt und die Anzahl der Datenfelder.
4.) Mache erst im Erfolgsfall ein http://dev.mysql.com/doc/refman/5.0/en/load-data.html - prüfe auch hier die Fehlermeldungen und stelle sicher (über einen Flöag?), dass Du die Daten wieder sauber löschen kannst, falls ein Fehler auftrat.
Du siehst das Problem besteht eigentlich daran den Importerfolg der Daten "transaktional" sicherzustellen.
Du siehst das Problem besteht eigentlich daran den Importerfolg der Daten "transaktional" sicherzustellen.
Aha - obwohl ich fast nichts von dem verstehe was Du schreibst werde ich mich mal versuchen durchzukämpfen.
Danke vorerst :)
Du siehst das Problem besteht eigentlich daran den Importerfolg der Daten "transaktional" sicherzustellen.
Aha - obwohl ich fast nichts von dem verstehe was Du schreibst werde ich mich mal versuchen durchzukämpfen.
Danke vorerst :)
Es geht darum sicherzustellen, dass Du die Daten entweder en bloc importierst oder eben gar nicht importierst, oder?
Beachte auch:
"
When the LOAD DATA INFILE statement finishes, it returns an information string in the following format:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
If you are using the C API, you can get information about the statement by calling the mysql_info() function. See Section 22.2.3.35, “mysql_info()”.
Warnings occur under the same circumstances as when values are inserted via the INSERT statement (see Section 13.2.4, “INSERT Syntax”), except that LOAD DATA INFILE also generates warnings when there are too few or too many fields in the input row. The warnings are not stored anywhere; the number of warnings can be used only as an indication of whether everything went well.
You can use SHOW WARNINGS to get a list of the first max_error_count warnings as information about what went wrong. See Section 13.5.4.28, “SHOW WARNINGS Syntax”.
"
Hello,
$handle = fopen ("uploads/haendler_deutschland.csv","r");
$row = 0;
while ($data = fgetcsv ($handle, 1000, ";"))
{
$row++;
echo "<p>Zeile: $row, Spalten: ".count($data);
$query = "INSERT INTO brd(
id
,name
,strasse
,plz
) VALUES('', '".$data[1]."', '".$data[2]."', '".$data[3]."')";
$result = mysql_query($query) or die("Invalid query: " . mysql_error().__LINE__.__FILE__);
echo ", Ergebnis ".( ($result===false) ? 'Fehler' : 'Ok')."</p>";
}
fclose ($handle);
Das sollte Die erstmal helfen, die Geschichte zu debuggen.
Dun nutzt CSV nicht sicher. Dazu müsstest Du auch Feldbegrenzer verwenden und berücksichtigen.
Anderenfalls würden Umbrüche, Feldtrenner und Feldbegrenzer in Datenwerten immer Schwierigkeiten machen. Aus diesem Grunde solltest Du dann auch mysql_real_escape_string() noch verwenden, um den Wert für die DB vorzubereiten.
Harzliche Grüße
http://www.annerschbarrich.de
Tom