Nếu bạn thực hiện echo($sql);
trước khi thực thi, bạn sẽ thấy rằng cú pháp truy vấn của mình không chính xác vì những lý do sau:
-
Tên tệp phải được đặt trong dấu ngoặc kép thay vì dấu gạch ngược vì nó là một chuỗi ký tự không phải là một số nhận dạng.
-
Hoàn toàn không cần gọi
mysql_escape_string()
để chỉ định dấu phân tách trongFIELDS TERMINATED BY
vàENCLOSED BY
vàESCAPED BY
mệnh đề. -
Bạn sử dụng quá nhiều backticks. Thực tế trong trường hợp của bạn, vì không có từ dành riêng nào được sử dụng, bạn bỏ tất cả chúng đi. Chúng chỉ thêm lộn xộn.
-
Ở cuối dòng đầu tiên của tệp CSV, bạn phải có
,,,
bởi vì bạn sử dụng chúng như một phần của dấu phân cách dòng. Nếu bạn không làm như vậy, bạn sẽ bỏ qua không chỉ dòng đầu tiên mà còn bỏ qua dòng thứ hai chứa dữ liệu. -
Bạn không thể sử dụng
ENCLOSED BY
mệnh đề nhiều hơn một lần. Bạn phải đối phó vớiNumber
theo một cách khác. -
Nhìn vào các hàng mẫu của bạn NGAY LẬP TỨC, bạn không cần
ESCAPED BY
. Nhưng nếu bạn cảm thấy cần nó, hãy sử dụng nó như thế nàyESCAPED BY '\\'
.
Điều đó được cho là một câu lệnh đúng về mặt cú pháp có thể trông như thế này
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)
Bây giờ IMHO, bạn cần phải chuyển đổi khá nhiều trường trong khi tải chúng:
-
nếu
date
trong bảng của bạn làdatetime
kiểu dữ liệu thì nó cần được chuyển đổi, nếu không bạn sẽ gặp lỗiGiá trị ngày giờ không chính xác:'Ngày 18 tháng 9 năm 2013 01:53:45 CH' cho cột 'ngày tháng' ở hàng
-
bạn phải đối phó với các qoutes đơn lẻ xung quanh các giá trị trong
Number
lĩnh vực -
bạn rất có thể muốn thay đổi
"null"
chuỗi ký tự thànhNULL
thực tế choaddr, pin, city, state, country
cột -
nếu thời lượng luôn tính bằng giây thì bạn có thể trích xuất một giá trị số nguyên của giây và lưu trữ theo cách đó trong bảng của mình để có thể dễ dàng tổng hợp các giá trị thời lượng sau này.
Điều đó được cho là một phiên bản hữu ích của câu lệnh sẽ trông giống như thế này
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')
Dưới đây là kết quả thực hiện truy vấn trên máy của tôi
mysql> LOAD DATA INFILE '/tmp/detection.csv' -> INTO TABLE calldetections -> FIELDS TERMINATED BY ',' -> OPTIONALLY ENCLOSED BY '"' -> LINES TERMINATED BY ',,,\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'); Query OK, 3 rows affected (0.00 sec) Records: 3 Deleted: 0 Skipped: 0 Warnings: 0 mysql> select * from calldetections; +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ | date | name | type | number | duration | addr | pin | city | state | country | lat | log | +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ | 2013-09-18 13:53:45 | Unknown | outgoing call | 123456 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:14 | Unknown | outgoing call | 1234567890 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:37 | Unknown | outgoing call | 14772580369 | 1 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ 3 rows in set (0.00 sec)
Và cuối cùng trong php gán một chuỗi truy vấn cho $sql
biến sẽ giống như thế này
$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') ";