使用PHP/MySQL-Mysqli语法导入CSV数据



在这个问题的底部,最后一个代码终于起作用了!

尝试实现这一点(使用PHP/MMySQL导入CSV数据)。我一定快到了。。。

注1:我的$sql直接来自于复制/粘贴phpmyadmin(生成php代码),并且在phpmyadmin中运行得很好。

注2:如果我对$sql="DELETE FROM dbase"这一行进行注释,代码运行得很好(并且表已清理)。

所以,如果我知道我的sql是正确的,并且我的代码可以运行其他sql,为什么下面的不运行?!我得到:

调用非对象上的成员函数execute()-对于行

$stmt->execute();

完整代码:

<?php
$mysqli  =  new mysqli('localhost','root','pass','dbase');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %sn", mysqli_connect_error());
exit();
}
$sql = "LOAD DATA INFILE './myfile.csv' INTO TABLE tabn"
. " FIELDS TERMINATED BY ','n"
. " LINES TERMINATED BY '\r\n'n"
. " IGNORE 1 LINES";
//$sql="DELETE FROM dbase";
$stmt=$mysqli->prepare($sql);
$stmt->execute(); 
$stmt->close();
$mysqli->close();
?>

tks提前!

编辑:

进行了以下更改,但仍然不起作用!

新代码:

<?php
$mysqli  =  new mysqli('localhost','root','pass','dbase');
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %sn", mysqli_connect_error());
    exit();
}
/* return name of current default database */
if ($result = $mysqli->query("SELECT DATABASE()")) {
    $row = $result->fetch_row();
    printf("Default database is %s.n", $row[0]);
    $result->close();
}
$sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab
        FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\r\n'
    IGNORE 1 LINES";
echo "<br>";
echo "<br>";
echo $sql;
echo "<br>";
echo "<br>";
$stmt=$mysqli->prepare($sql);
/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare($sql))) 
{    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

// NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS 
// CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT   
var_dump($mysqli);
exit();
//$sql="DELETE FROM intrasdump
$stmt=$mysqli->prepare($sql);
$stmt->execute(); 
$stmt->close();
$mysqli->close();
?>

当我运行这个程序时,我在浏览器中看到的内容如下:

默认数据库为dbname。

将数据文件"C:\xamplep/htdocs/myfile.csv"加载到表选项卡字段"终止于","终止于的行"\r\n"忽略1行

准备失败:(1295)已准备好的语句协议yethobject(mysqli)#1(19){["affected_rows"]=>int(-1)["client_info"]=>string(79)"mysqlnd 5.0.11-dev-20120503-$Id:40933630edef551dfaca71298a83fad8d03d62d4$"["client_version"]=>int(50011 error"]=>字符串(68)"准备好的语句协议中还不支持此命令"["error_list"]=>array(0){}["field_count"]=>int(1)["host_info"]=>string(20)"localhost via TCP/IP"["info"]=>NULL["insert_id"]=>int(0)["server_info"]=>string"正常运行时间:7993个线程:2个问题:865个慢速查询:0个打开:75个刷新表:1个打开表:每秒68个查询平均值:0.108"["sqlstate"]=>string(5)"00000"["protocol_version"]=>int(10)["thread_id"]=>int[(117)["warning_count"]=>int(0)}

注意:如果我将上面呼应的sql字符串复制粘贴到mysql提示符中,它运行得很好。这应该意味着文件位置问题和sql字符串本身都很好,不是吗???

这怎么这么难?!

编辑3。

谢谢所有的回答和评论。以下工作的最终代码版本:

<?php
$mysqli  =  new mysqli('localhost','root','pass','dbname');
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %sn", mysqli_connect_error());
    exit();
}
$sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab
        FIELDS TERMINATED BY ','
        LINES TERMINATED BY '\r\n'
        IGNORE 1 LINES";
//Try to execute query (not stmt) and catch mysqli error from engine and php error
if (!($stmt = $mysqli->query($sql))) {
    echo "nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
};
?>

有用的注释:

  • 请注意,文件路径使用frw-slash,而不是windows默认的反斜杠。有序只会记录工作。天知道我是怎么想出来的。。。

  • 利用答案中提供的许多调试代码。我想检查sql是否正确的一种有效方法是回显(echo $sql)它并在sql提示符中复制/粘贴。不要相信phpmyadmin的"创建phpPHP代码"功能。

  • 请记住"准备好的stmts不支持LOAD DATA"

编辑可能的解决方案:准备好的stmt不支持LOAD DATA

如果使用mysqli_query-而不是mysqli->prepare.->execute();这应该行得通。

因此:

//Connect as normal above
$sql = "LOAD DATA INFILE '/myfile.csv' INTO TABLE tab"
. " FIELDS TERMINATED BY ','"
. " LINES TERMINATED BY 'rn'"
. " IGNORE 1 LINES";
//$sql="DELETE FROM dbase";
// $stmt = $mysqli->query($sql);
// Integrate other posters good recc to catch errors:
//Try to execute query (not stmt) and catch mysqli error from engine and php error
if (!($stmt = $mysqli->query($sql))) {
    echo "nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
}

仍然有用的var_dump($mysqli)在这里查看结果我得到访问被拒绝,因为在我的env中我们不允许LOAD FILE,但这告诉我引擎成功解析并尝试执行查询。

你需要获得更好的错误信息,可能会发生一些事情,以下是我将如何挖掘:

达到这一点的诊断过程:

$sql = "LOAD DATA INFILE ...";
echo $sql;
$stmt=$mysqli->prepare($sql);
// NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS 
// CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT   
var_dump($mysqli);
exit();

我的盒子上的结果(不是最佳表示):

  object(mysqli)#1 (18) {
  ...
  string(68) "This command is not supported in the 
              prepared statement protocol yet"

2.您可能看到的其他错误

文件权限不足或文件位置目录不正确

phpMyAdmin是非常沙盒的,它的工作方式与mysqli/php完全不同。

从MySQL文档中处理以下内容,并阅读本节内容。就像我说的,LOAD。。FILE是一个非常敏感的操作,有很多限制。LOAD...FILE MySQL文档

出于安全原因在读取位于服务器上的文本文件时,文件必须位于数据库目录中或可读所有人。此外,要在服务器文件上使用LOAD DATA INFOILE,您必须FILE特权。请参阅第6.2.1节"MySQL提供的权限"。对于非LOCAL加载操作,如果secure_file_priv系统变量设置为非空目录名,则要加载的文件必须为位于该目录中。

当准备调用失败时,您可能应该设置保护来检测:

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

来源:http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php

我还要检查LOAD DATA INFILE命令的路径。Phpmyadmin可能正在设置不同的路径变量。如果您尝试暂时放置绝对的unix路径(并确保mysql对该目录具有适当的权限),它可能会解决问题。

然而,在任何一种情况下,您都应该从mysql客户端输出错误,以便更好地了解问题的原因。

最后,我会尝试直接在MySQL命令行客户端中执行该命令。如果phpmysql或mysqli-php客户端中发生了任何"魔术",它将通过使用mysql-cli客户端来显示,因为其中两个客户端将成功,而一个客户端将失败(与您的假设相比)。

我以前遇到过类似的问题,它最终成为MySQL转义分隔符的奇怪方式,所以我希望您能正确地转义TERMINATED BY参数。

Homer6的状态,可能还有:

$sql = "LOAD DATA INFILE './myfile.csv' INTO TABLE tab"
. " FIELDS TERMINATED BY ','"
. " LINES TERMINATED BY '\r\n'"
. " IGNORE 1 LINES";

可能还需要检查文件的路径。我不知道是什么。/是相对于查询中的。也许不是PHP文件的位置。

您必须使用MySQL的根用户如果它仍然无法运行,请使用此代码检查错误输出

var_dump(mysqli_error($conn));

最新更新