我正在尝试将CSV文件导入MySQL数据库,但它无效。
我的数据库中有5列:
id,userID,movieID,rate,timestamp
在我的CSV文件中,我只有4列用两个冒号'::'分隔 这是样本数据:
1 :: 1193 :: 5 :: 978300760
这是我的查询
$ query =“LOAD DATA INFILE'$ uploadfile'INTO TABLE rating_table 由'\ n'终止的'::'线路终止的字段( userID,movieID,rate,timestamp)“;
我正在使用PDO_MySQL
这是附加代码,以便您可以理解。
$stmt = $dbh->prepare($query);
try{
if($stmt->execute()){
echo "Sucessful importing of CSV file into the MySQL database!";
}
}
catch (PDOException $e) {
echo "Error importing of CSV file into the MySQL database!";
echo "Error!: " . $e->getMessage() . "<br/>";
die();
}
echo "</p>";
我已经尝试了很多次但是当我检查了我的数据库时,它仍然是空的 我似乎无法弄清楚出了什么问题,你能帮助我吗?谢谢!
这是我的错误。
致命错误:带有消息的未捕获异常'PDOException' 'SQLSTATE [HY000]:常规错误:2014无法执行查询 其他未缓冲的查询处于活动状态。考虑使用 PDOStatement对象::使用fetchall()。或者,如果您的代码只是永远 要对mysql运行,您可以通过设置启用查询缓冲 PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性。'在 C:\ xampp \ htdocs \ movie \ php \ upload_file.php:57堆栈跟踪:#0 C:\ xampp \ htdocs \ movie \ php \ upload_file.php(57):PDOStatement-&gt; execute() 在第57行的C:\ xampp \ htdocs \ movie \ php \ upload_file.php中抛出1 {main}
这是我的连接设置:
$ dbh = new PDO('mysql:host = localhost; dbname = movie','root','', 阵列( PDO :: MYSQL_ATTR_INIT_COMMAND =&gt; “SET NAMES UTF8”, PDO :: ATTR_EMULATE_PREPARES =&gt;假, PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY =&gt;真正, PDO :: ATTR_ERRMODE =&gt; PDO :: ERRMODE_EXCEPTION,PDO :: MYSQL_ATTR_LOCAL_INFILE =&gt;真正 ));
答案 0 :(得分:5)
要在输出中查看错误消息,只需使用PDO::ERRMODE_EXCEPTION
初始化您的PDO,如下所示:
$db = new PDO('mysql:host=' . $config['db_host'] . ';dbname=' . $config['db_name'], $config['db_username'], $config['db_password'],
array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8",
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
之后您将能够看到错误。将其发布在更新中,我/我们将能够帮助您!
查看PDO_MYSQL上的手册。
您可能还需要:
PDO::MYSQL_ATTR_LOCAL_INFILE => TRUE
注意,此常量只能在driver_options数组中使用 构建一个新的数据库句柄。
根据MySQL Manual,MySQL必须使用--enable-local-infile
编译:
你必须使用MySQL的完整路径编译PHP,否则它 将使用它的内部处理程序,它不适用于“新”LOAD 数据。
- with-mysql = / usr / local / mysql(假设您的MySQL位于此处)
您必须使用选项'--local-infile = 1'
启动MySQL守护程序
或通过添加到/etc/my.cnf
:
[mysql]
local-infile=1
[mysqld]
local-infile=1
之后,通过运行mysqld
重新启动service mysqld restart
。
引号用于字符串文字,用于列和表名称的后退。正确地转义变量。将您的查询更改为:
$query = "LOAD DATA INFILE ' . $uploadfile . ' INTO TABLE `rating_table` FIELDS TERMINATED BY '::' LINES TERMINATED BY '\n' ( `userID`, `movieID`, `rate`, `timestamp`)";
当您同时有多个查询open
时,通常会导致此错误。例如,您调用fetch()
,但在完成之前不会调用它,然后尝试执行第二次查询。
通常,此问题的解决方案是致电closeCursor()
PHP: PDOStatement::closeCursor - Manual。试着调用:
/* The following call to closeCursor() may be required by some drivers */
$stmt->closeCursor();
/* Now we can execute the second statement */
$otherStmt->execute();
并查看是否会为您改变任何内容。
尝试使用其他语法来转义变量。使用以下内容:
$stmt = $dbh->prepare("
LOAD DATA INFILE
'" . $uploadfile . "'
INTO TABLE
`rating_table`
FIELDS TERMINATED BY
'::'
LINES TERMINATED BY
'\n' ( `userID`, `movieID`, `rate`, `timestamp`)
");
$stmt->execute();
PDO占位符只能用于值,而不能用于数据库,表或列名称!我认为错误来自使用'::'
。将文件中的数据分隔符从'::'
更改为'.'
。
作为检查的快速解决方法,您可以直接使用查询而无需准备:
$stmt = $dbh->query("
LOAD DATA INFILE
'" . $uploadfile . "'
INTO TABLE
`rating_table`
FIELDS TERMINATED BY
'::'
LINES TERMINATED BY
'\n' ( `userID`, `movieID`, `rate`, `timestamp`)
");
如果不起作用,请尝试更改数据分隔符或尝试以某种方式转义现有的删除程序(::
)。
答案 1 :(得分:0)
您的LOCAL
声明中可能缺少LOAD DATA INFILE
个关键字。
LOCAL
表示您加载的文件位于客户端而不是服务器上。当我尝试使用你的表和文件时,它运行正常。
> cat infile.csv
1::1193::5::978300760
> mysql
mysql > create table ratings (
id int primary key auto_increment,
userID int,
movieID int,
rate int,
ts long);
Query OK, 0 rows affected (0.06 sec)
mysql > LOAD DATA LOCAL INFILE 'infile.csv' INTO TABLE ratings FIELDS TERMINATED BY '::' LINES TERMINATED BY '\n' ( userID, movieID, rate, ts);
Query OK, 1 row affected (0.00 sec)
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
mysql > select * from ratings;
+----+--------+---------+------+-----------+
| id | userID | movieID | rate | ts |
+----+--------+---------+------+-----------+
| 1 | 1 | 1193 | 5 | 978300760 |
+----+--------+---------+------+-----------+
1 row in set (0.00 sec)