Ich habe eine solche CSV-Datei
Date,Name,Call Type,Number,Duration,Address,PostalCode,City,State,Country,Latitude,Longitude
"Sep-18-2013 01:53:45 PM","Unknown","outgoing call",'123456',"0 Secs","null","null","null","null","null",0.0,0.0,,,
"Sep-18-2013 01:54:14 PM","Unknown","outgoing call",'1234567890',"0 Secs","null","null","null","null","null",0.0,0.0,,,
"Sep-18-2013 01:54:37 PM","Unknown","outgoing call",'14772580369',"1 Secs","null","null","null","null","null",0.0,0.0,,,
und ich verwende den folgenden Code, um die Daten in die Datenbank einzufügen
$sql = "LOAD DATA INFILE `detection.csv`
INTO TABLE `calldetections`
FIELDS TERMINATED BY '"[email protected]_escape_string(",").
"` OPTIONALLY ENCLOSED BY `"[email protected]_escape_string("\"").
"` OPTIONALLY ENCLOSED BY `"[email protected]_escape_string("\'").
"` ESCAPED BY `"[email protected]_escape_string("\\").
"` LINES TERMINATED BY `".",,,\\r\\n".
"`IGNORE 1 LINES `"
."(`date`,`name`,`type`,`number`,`duration`,`addr`,`pin`,`city`,`state`,`country`,`lat`,`log`)";
$res = @mysql_query($con,$sql);
aber nichts wird eingefügt; wo ist der fehler
Wenn Sie echo($sql);
ausführen, bevor Sie es ausführen, wird die Syntax Ihrer Abfrage aus folgenden Gründen falsch sein:
Dateiname sollte in Anführungszeichen und nicht in Backticks stehen, da es sich um ein String-Literal und nicht um einen Bezeichner handelt.
Es ist absolut nicht erforderlich, mysql_escape_string()
aufzurufen, um ein Trennzeichen in den Klauseln FIELDS TERMINATED BY
und ENCLOSED BY
und ESCAPED BY
anzugeben.
Sie überbieten Backticks. Da in Ihrem Fall keine reservierten Wörter verwendet werden, geben Sie sie alle auf. Sie fügen nur Unordnung hinzu.
Am Ende der allerersten Zeile Ihrer CSV-Datei müssen Sie müssen,,,
haben, da Sie sie als Teil eines Trennzeichens verwenden. Wenn Sie dies nicht tun, überspringen Sie nicht nur die erste Zeile, sondern auch die zweite Zeile, die Daten enthält.
Sie können die Klausel ENCLOSED BY
nur einmal verwenden. Sie müssen das Feld Number
anders behandeln.
Wenn Sie Ihre Beispielzeilen betrachten, benötigen Sie IMHO nicht ESCAPED BY
. Wenn Sie das Gefühl haben, dass Sie es brauchen, verwenden Sie es wie folgt: ESCAPED BY '\\'
.
Davon ausgehend könnte eine syntaktisch korrekte Aussage so aussehen
LOAD DATA INFILE 'detection.csv'
INTO TABLE calldetections
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY ',,,\r\n'
IGNORE 1 LINES
(date, name, type, number, duration, addr, pin, city, state, country, lat, log)
IMHO müssen Sie beim Laden einige Felder umwandeln:
wenn date
in Ihrer Tabelle vom Datentyp datetime
ist, muss er umgewandelt werden, andernfalls erhalten Sie eine Fehlermeldung
Falscher Datums-/Uhrzeitwert: "Sep-18-2013 13:53:45 PM" für Spalte "Datum" in Zeile
sie müssen mit einzelnen Qoutes um die Werte im Feld Number
umgehen
sie möchten "null"
-Stringliteral wahrscheinlich in NULL
für addr, pin, city, state, country
-Spalten ändern
wenn die Dauer immer in Sekunden ist, können Sie einen ganzzahligen Sekundenwert extrahieren und so in Ihrer Tabelle speichern, um die Dauerwerte später einfach zusammenfassen zu können.
Davon abgesehen sollte eine nützliche Version der Erklärung in etwa so aussehen
LOAD DATA INFILE 'detection.csv'
INTO TABLE calldetections
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY ',,,\r\n'
IGNORE 1 LINES
(@date, name, type, @number, @duration, @addr, @pin, @city, @state, @country, lat, log)
SET date = STR_TO_DATE(@date, '%b-%d-%Y %h:%i:%s %p'),
number = TRIM(BOTH '\'' FROM @number),
duration = 1 * TRIM(TRAILING 'Secs' FROM @duration),
addr = NULLIF(@addr, 'null'),
pin = NULLIF(@pin, 'null'),
city = NULLIF(@city, 'null'),
state = NULLIF(@state, 'null'),
country = NULLIF(@country, 'null')
Unten ist das Ergebnis der Ausführung der Abfrage auf meinem Rechner
mysql> LOAD DATA INFILE '/tmp/detection.csv' -> INTO TABLE Anruferkennung -> FELDER BEENDET DURCH ',' -> OPTIONAL EINGESCHLOSSEN DURCH '"' -> LINES DURCH ',\n' -> IGNORE 1 LINES -> (@date, name, type, @number, @duration, @addr, @pin, @city, @state, @country, lat, log) -> SET date = STR_TO_DATE (@date, '% b-% d-% Y% h:% i:% s% p '), -> number = TRIM (BEIDE'\'' FROM @number), -> duration = 1 * TRIM (TRAILING 'Secs' FROM @duration), -> addr = NULLIF (@addr, 'null'), -> pin = NULLIF (@pin, 'null'), -> city = NULLIF (@city, 'null'), -> state = NULLIF (@State, 'null'), -> country = NULLIF (@country, 'null'); Abfrage OK, 3 betroffene Zeilen (0,00 Sek.) Datensätze: 3 Gelöscht: 0 Übersprungen: 0 Warnungen: 0 Mysql> Wählen Sie * aus den Anruferkennungen; + --------------------- + ----- ---- + --------------- + ------------- + ---------- + ---- - + ------ + ------ + ------- + --------- + ------ + ------ + | Datum | Name | Typ | Nummer | Dauer | Addr | Pin | Stadt | Bundesland | Land | Lat | Log | + --------------------- + --------- + ------------- - + ------------- + ---------- + ------ + ------ + ------ + - ------ + --------- + ------ + ------ + | 2013-09-18 13:53:45 | Unbekannt | ausgehender Anruf | 123456 | 0 | NULL | NULL | NULL | NULL | NULL | 0,0 | 0,0 | | 2013-09-18 13:54:14 | Unbekannt | ausgehender Anruf | 1234567890 | 0 | NULL | NULL | NULL | NULL | NULL | 0,0 | 0,0 | | 2013-09-18 13:54:37 | Unbekannt | ausgehender Anruf | 14772580369 | 1 | NULL | NULL | NULL | NULL | NULL | 0,0 | 0.0 | + --------------------- + --------- + ------------ --- + ------------- + ---------- + ------ + ------ + ------ + ------- + --------- + ------ + ------ + 3 Reihen in Satz (0,00 s)
Und schließlich sollte in php die Zuweisung einer Abfragezeichenfolge an die Variable $sql
so aussehen
$sql = "LOAD DATA INFILE 'detection.csv'
INTO TABLE calldetections
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY ',,,\\r\\n'
IGNORE 1 LINES
(@date, name, type, @number, @duration, @addr, @pin, @city, @state, @country, lat, log)
SET date = STR_TO_DATE(@date, '%b-%d-%Y %h:%i:%s %p'),
number = TRIM(BOTH '\'' FROM @number),
duration = 1 * TRIM(TRAILING 'Secs' FROM @duration),
addr = NULLIF(@addr, 'null'),
pin = NULLIF(@pin, 'null'),
city = NULLIF(@city, 'null'),
state = NULLIF(@state, 'null'),
country = NULLIF(@country, 'null') ";
mysqli_query($cons, '
LOAD DATA LOCAL INFILE "'.$file.'"
INTO TABLE tablename
FIELDS TERMINATED by \',\'
LINES TERMINATED BY \'\n\'
IGNORE 1 LINES
(isbn10,isbn13,price,discount,free_stock,report,report_date)
SET RRP = IF(discount = 0.00,price-price * 45/100,IF(discount = 0.01,price,IF(discount != 0.00,price-price * discount/100,@RRP))),
RRP_nl = RRP * 1.44 + 8,
RRP_bl = RRP * 1.44 + 8,
ID = NULL
')or die(mysqli_error());
$affected = (int) (mysqli_affected_rows($cons))-1;
$log->lwrite('Inventory.CSV to database:'. $affected.' record inserted successfully.');
RRP und RRP_nl und RRP_bl ist nicht in csv, aber wir berechnen das und nach dem Einfügen.