CodeIgniter 3 的 insert_batch() 是最直接的批量插入方案,原生支持、语法简洁且已优化SQL合并;CI4 的 insertBatch() 更严格,要求字段名完全匹配表结构,并需注意空值、长度限制及事务包裹。

CodeIgniter 3 中 insert_batch() 是最直接的批量插入方案
它原生支持、语法简洁,且底层已做 SQL 合并优化。调用前确保数据是二维数组,每项对应一条记录的字段键值对:
-
$data必须是数组的数组,例如[ ['name' => 'A', 'age' => 20], ['name' => 'B', 'age' => 22] ] - 所有子数组的键名必须一致,缺失字段会变成
NULL(除非字段有默认值或允许为空) - 不校验字段是否存在,字段名错写会导致 SQL 错误,如
Unknown column 'user_nam' in 'field list' - 执行后返回布尔值,失败时不抛异常,需手动检查:
if ($this->db->insert_batch('users', $data) === FALSE) { log_message('error', $this->db->error()); }
CodeIgniter 4 的 insertBatch() 行为更严格
CI4 默认开启严格模式,字段名必须与数据库表结构完全匹配,且不自动忽略多余键。常见踩坑点:
- 传入含时间戳字段(如
created_at)时,若未设置$this->table = 'users'或未启用自动时间戳,会因字段不存在报错 - 数据中包含空字符串
''或null,而对应字段设为NOT NULL,直接触发数据库约束错误 - 批量条数过大(如超 5000 条)可能触发 MySQL 的
max_allowed_packet限制,建议分批,每次 ≤ 1000 条 - 示例写法:
$this->model->insertBatch($data);,注意模型需继承CodeIgniter\Model且已指定表名
绕过框架批量方法、手写 INSERT 多值语句的适用场景
当需要精确控制字段顺序、插入计算值(如 NOW()、UUID()),或兼容老版本 CI(如 2.x)时,可拼接原生 SQL:
- 用
$this->db->escape()逐个处理值,避免 SQL 注入;不要直接字符串拼接用户输入 - 单条
INSERT ... VALUES (...), (...), (...)最多支持约 1000 组值,超出建议拆成多个语句 - CI3 示例:
$sql = "INSERT INTO users (name, created_at) VALUES " . implode(',', $valuePairs); $this->db->query($sql);,其中$valuePairs是转义后的字符串数组 - CI4 更推荐用 Query Builder 的
set()+ignore()配合循环,但性能不如原生批量,仅适合小规模灵活写入
事务包裹 + 批量插入是保障数据一致性的必要操作
批量不是原子操作,中途出错会导致部分写入。尤其在关联表插入或依赖主键返回值时,必须加事务:
- CI3:用
$this->db->trans_start()/$this->db->trans_complete()包裹insert_batch() - CI4:用
$this->db->transBegin()+$this->db->transCommit()/$this->db->transRollback() - 注意事务内不要混用不同数据库连接(如同时操作 MySQL 和 PostgreSQL),CI 不支持跨驱动事务
- 如果批量中某条记录违反唯一索引,整个事务回滚——这是预期行为,不是 bug
实际用的时候,优先走框架自带的 insert_batch() 或 insertBatch(),别急着手写 SQL;但字段映射不清晰、数据来源不可控、或要插几千条时,分批+事务+预处理才是稳住的关键。











