使用MySQLi预处理语句导入CSV数据(PHP数组)报错求助
问题分析与解决方案
你的错误根源是prepare()执行失败返回了false,导致后续调用bind_param()时出错。主要问题出在SQL语句的字段名格式上,另外代码还有可优化的空间,具体修正如下:
1. 修正SQL字段名格式
MySQL中字段名不能用单引号包裹(单引号仅用于字符串值),你需要把字段名的单引号替换成反引号(`),若字段名不是MySQL关键字,也可以直接去掉引号:
原错误SQL:
INSERT INTO sov ('BID', 'costcode', 'bidpack', 'item', 'um', 'qty', 'est', 'up') VALUES (?,?,?,?,?,?,?,?)
修正后:
INSERT INTO sov (`BID`, `costcode`, `bidpack`, `item`, `um`, `qty`, `est`, `up`) VALUES (?,?,?,?,?,?,?,?)
2. 优化预处理语句位置
每次循环都重新执行prepare()会降低效率,应将预处理操作移到循环外,仅执行一次,循环内重复绑定参数并执行即可。
3. 可选:跳过CSV表头行
如果你的CSV第一行是字段名称而非数据,需在循环开始前调用一次fgetcsv()跳过表头,避免表头被插入数据库。
4. 添加错误排查逻辑
在prepare()和execute()后添加判断,输出具体错误信息,方便调试。
修正后的完整代码
if(isset($_FILES['upload'])) { if (($handle = fopen($_FILES['upload']['tmp_name'], 'r')) !== FALSE) { // 预处理语句移到循环外 $stmt = $connection->prepare("INSERT INTO sov (`BID`, `costcode`, `bidpack`, `item`, `um`, `qty`, `est`, `up`) VALUES (?,?,?,?,?,?,?,?)"); // 检查预处理是否成功 if (!$stmt) { die("预处理失败: " . $connection->error); } // 绑定参数(先绑定变量,循环内给变量赋值) $stmt->bind_param('ssssssss', $bid, $costcode, $bidpack, $item, $um, $qty, $est, $up); // 跳过CSV表头行(无表头则注释此行) fgetcsv($handle, 1000, ","); while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) { // 给绑定的变量赋值 $bid = $row[0]; $costcode = $row[1]; $bidpack = $row[2]; $item = $row[3]; $um = $row[4]; $qty = $row[5]; $est = $row[6]; $up = $row[7]; // 执行语句并捕获错误 if (!$stmt->execute()) { echo "插入失败: " . $stmt->error . "<br>"; } } $stmt->close(); fclose($handle); } }
内容的提问来源于stack exchange,提问作者Br549
相关产品推荐
相关产品推荐

