Laravel如何解决插入数据时出现的「Does not have a default value」报错
报错根因:混用Eloquent的
insert()方法与实例save(),触发了多余的空插入 执行流程拆解(对应你遇到的所有现象)
- 你执行
$news = new News时,只是初始化了一个没有任何业务字段的空Eloquent模型实例 - 调用
$news->insert([...])时,这个方法不会将传入的业务字段赋值到当前模型实例,本质是委托模型绑定的查询构造器直接执行SQL插入:这一步会把你传入的title、content等字段直接写入数据库,执行完成后$news依然是没有任何业务属性的空对象。 - 紧接着你调用
$news->save(),这个空模型实例会尝试执行一次插入操作:因为实例上没有任何业务字段,生成的INSERT语句只会包含Eloquent自动填充的created_at、updated_at两个字段,也就是你报错日志里记录的那条SQL。
为什么报错但数据依然正常入库
你看到的已经存入数据库的正常数据,是第二步insert()方法执行成功的结果;报错的来源是第三步save()触发的空插入尝试。因为你的news表中title、content等业务字段都是非空、无数据库默认值的,无法执行这条只带两个时间字段的插入语句,数据库就抛出了“字段没有默认值”的错误。
由于两次插入是独立的自动提交操作,第一步insert执行完成后数据就已经写入磁盘,哪怕后面的save操作报错,之前的业务数据也不会被回滚,这就是你会感觉“报错但数据正常”的原因。
正确修正方案(二选一即可)
- 采用Eloquent模型赋值写入的方式,去掉多余的
insert()调用,依赖模型自带的时间戳自动维护能力:public function addArticle(Request $request) { $data = $request->json()->all(); $news = new News; // 直接给模型实例赋值业务字段,无需手动传created_at/updated_at $news->title = $data['title']; $news->content = $data['content']; $news->photo = $data['photo']; $news->author = 1; $news->save(); } - 采用查询构造器批量插入的方式,去掉多余的
$news->save()调用:public function addArticle(Request $request) { $data = $request->json()->all(); // 直接静态调用insert,不需要额外new模型实例 News::insert([ 'title' => $data['title'], 'content' => $data['content'], 'photo' => $data['photo'], 'author' => 1, "created_at"=> now(), "updated_at"=> now(), ]); }
注意:查询构造器的
insert()不会触发Eloquent模型事件,也不会自动维护时间字段,用这种方式插入时需要手动传入created_at和updated_at;而模型实例的save()方法会自动处理这两个时间字段,不需要手动赋值。
内容的提问来源于stack exchange,提问作者Kerchik
相关产品推荐
相关产品推荐

