如何在Laravel 9项目中捕获MySQL/MariaDB重复主键异常?
处理邮箱重复的SQL约束异常
在Laravel控制器中,你可以通过try-catch捕获QueryException来处理该重复插入错误,具体实现步骤如下:
- 先引入需要的异常类(如果控制器顶部未引入):
use Illuminate\Database\QueryException;
- 将插入逻辑包裹在try块中,捕获异常并判断错误类型:
if (isset($_POST['nom'], $_POST['prenom'], $_POST['email'], $_POST['cities'])) { $nom = request('nom'); $prenom = request('prenom'); $email = request('email'); $ville = request('cities'); try { DB::insert('insert into newsletter (nom, prenom, email, ville) values (?, ?, ?, ?)', [$nom, $prenom, $email, $ville]); // 插入成功后的逻辑,比如返回页面并提示成功 return back()->with('success', '订阅成功!'); } catch (QueryException $e) { // 匹配重复主键的错误码和信息 if ($e->getCode() === '23000' && str_contains($e->getMessage(), '1062')) { // 返回重复邮箱的错误提示 return back()->with('error', '该邮箱已订阅过,请更换邮箱重试!'); } // 其他数据库异常,可选择抛出或统一处理 throw $e; } }
- 前端视图可添加提示展示(可选):
@if(session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif @if(session('error')) <div class="alert alert-danger">{{ session('error') }}</div> @endif
补充方案:用Eloquent简化逻辑
如果你使用Laravel的Eloquent模型(需先创建Newsletter模型),可以用firstOrCreate方法自动处理重复情况,无需手动捕获异常:
// 自动判断email是否存在,不存在则插入新数据 $newsletter = Newsletter::firstOrCreate( ['email' => $email], ['nom' => $nom, 'prenom' => $prenom, 'ville' => $ville] ); // 区分新订阅还是已订阅 if ($newsletter->wasRecentlyCreated) { return back()->with('success', '订阅成功!'); } else { return back()->with('error', '该邮箱已订阅过,请更换邮箱重试!'); }
内容的提问来源于stack exchange,提问作者Ayoub
相关产品推荐
相关产品推荐

