CodeIgniter使用insert_batch批量插入报MySQL 1064错误如何解决
CodeIgniter框架agenda表批量插入1064语法报错排查与修复
错误现象
- 错误编号:1064,属于MySQL语法校验类报错
- 报错提示:SQL语法存在错误,需对照所用MySQL版本的官方手册,确认第1行附近
'Array'位置的正确语法规则 - 实际生成的非法SQL语句:
INSERT INTO agenda () VALUES ('15','1','$2y$10$zE94wOg6xEpMfgU8bMzMmeBdKyFbU9UkmbwcTnlxftyD8jISDBpvG','1','admin'), Array - 报错溯源:框架核心数据库驱动文件
C:/xampp/htdocs/rekrutmen/system/database/DB_driver.php第691行
根本原因定位
本次报错完全是传入insert_batch方法的数组结构不符合框架要求导致的,核心问题有两点:
- 待插入数组结构混叠:原控制器代码在初始化
$data数组后,直接将查询到的当前登录用户行数组赋值为$data的根级键($data['users'] = xxx),后续循环又通过array_push往同一个$data里追加待插入的记录元素。最终传给insert_batch的$data不是纯二维的记录集合,而是混合了非记录类的users键值对,框架遍历数组生成SQL时,无法从这个根级键里提取agenda表的字段名,导致生成的SQL字段列表为空。 - 记录内部嵌套无键多维数组:原代码在循环构造单条插入记录时,直接把整个用户查询数组
$data['users']不加键名、不拆出具体字段值地塞到单条记录数组里。框架解析这类无键嵌套数组时,会将数组类型的值直接序列化成字符串Array拼接到SQL语句末尾,最终触发语法错误。
CodeIgniter的insert_batch方法不会提前校验入参的数组结构,遇到结构不符合要求的内容时会直接拼接非法SQL,因此报错点会出现在框架的数据库驱动层,而非业务代码层。
修复方案
按照框架insert_batch的入参要求重构控制器层的数组构造逻辑,模型层原有批量插入方法无需调整,核心调整点:
- 拆分变量作用域:单独用独立变量存储当前登录用户的查询结果,不要和待批量插入的数组合并
- 构造纯二维的批量插入数组:每个顶层元素对应一条待插入记录,记录内部严格遵循
[agenda表字段名 => 字段值]的键值对结构,不存在嵌套数组、多余的根级键 - 避免循环内的变量覆盖:循环遍历的临时变量不要和外层遍历数组同名,防止逻辑偏差
- 明确提取用户信息中需要落库的字段值,绑定到agenda表的对应字段上,禁止直接把整个多维数组嵌套到记录结构里
修正后的控制器核心代码:
// 单独存储当前登录用户信息,与待插入数组完全隔离 $current_user = $this->db->get_where('users', [ 'username' => $this->session->userdata('username') ])->row_array(); // 初始化纯二维的批量插入数据集 $batch_insert_data = []; $index = 0; foreach ($no_agenda as $agenda_no) { // 单条记录严格匹配agenda表的字段结构 $single_record = [ 'no_agenda' => $agenda_no, 'no_batch' => $no_batch[$index], 'nama_pelamar' => $nama_pelamar[$index], 'alamat' => $alamat[$index], 'no_hp' => $no_hp[$index], // 按需替换为agenda表实际存在的用户关联字段,如创建人ID、创建人账号 'created_by' => $current_user['id'], 'creator_account' => $current_user['username'] ]; $batch_insert_data[] = $single_record; $index++; } // 将符合结构要求的数据集传给模型层执行批量插入 $this->Agenda_model->save_batch($batch_insert_data);
注意:构造记录时要确认所有键名都是agenda表实际存在的字段,若表结构没有对应的用户关联字段,需要删除对应的键值对,否则会触发“未知字段”的SQL错误。
内容的提问来源于stack exchange,提问作者Lavenderian
相关产品推荐
相关产品推荐

