Laravel Eloquent字符串与日期联合查询报错修复方案
问题现象
单查询参数场景下代码运行正常,新增关键词搜索+日期范围多参数查询逻辑后,传入字符串关键词查询时抛出SQL错误,仅使用日期筛选时功能可正常运行。
关联代码片段
控制器编辑方法(AdminEditController)
class AdminEditController extends Controller { //edit didalam lihat_datafile public function edit(Request $request,$id){ $data = lokasipekerjaan::find($id); $data->mid=$request->mid; $data->subid=$request->subid; $data->pekerjaan=$request->pekerjaan; $data->lokasi=$request->lokasi; $data->uom=$request->uom; $data->cut=$request->cut; $data->fill=$request->fill; $data->area=$request->area; $data->tanggal=$request->tanggal; $data->save(); return redirect()->back(); } }
路由配置(web.php)
Route::resource('lokasipekerjaan', AdminEditController::class);
Blade模板表单代码
@foreach($data as $datas) <form action="{{route('lokasipekerjaan.edit',[$datas->id])}}" method="PUT"> <tr class="table-info"> <td> <input type="text" value="{{ $datas->id }}" class="" style="background-color: #E0FFFF;width:40px;height:40px;" name="id" :value="old('id')"> </input> </td> <td><input id="{{ $datas->mid }}" type="text" value="{{ $datas->mid }}" class="" style="background-color: #E0FFFF;width:40px;height:40px;" name="mid" :value="old('mid')"></td> <td> <input id="{{ $datas->subid }}" type="text" value="{{ $datas->subid }} " class="" style="background-color: #E0FFFF;width:100px;height:40px;" name="subid" :value="old('subid')"> </td> <td> <input id="{{ $datas->pekerjaan }}" type="text" value="{{ $datas->pekerjaan }} "class="" style="background-color: #E0FFFF;height:40px;" name="pekerjaan" :value="old('pekerjaan')"> </td> <td> <input id="{{ $datas->lokasi }}" type="text" value="{{ $datas->lokasi }} " class="" style="background-color: #E0FFFF;height:40px;" name="lokasi" :value="old('lokasi')"> </td> <td> <input id="{{ $datas->cut }}" type="text" value="{{ $datas->cut }} " class="" style="background-color: #E0FFFF;height:40px;" name="volume" :value="old('cut')"> </td> <td> <input id="{{ $datas->fill }}" type="text" value="{{ $datas->fill }} " class="" style="background-color: #E0FFFF;height:40px;" name="volume" :value="old('fill')"> </td> <td> <input id="{{ $datas->area }}" type="text" value="{{ $datas->area }} " class="" style="background-color: #E0FFFF;height:40px;" name="volume" :value="old('area')"> </td> <td> <input id="{{ $datas->uom }}" type="text" value="{{ $datas->uom }} " class="" style="background-color: #E0FFFF;width:40px;height:40px;" name="uom" :value="old('uom')"> </td> <td> <input value="{{ $datas->tanggal }} " type="text" value="{{ $datas->tanggal }} " class="" style="background-color: #E0FFFF;width:100px;height:40px;" name="tanggal" :value="old('tanggal')"> </td> <td> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{csrf_token()}}"> <input type="submit" onclick="return confirm('apakah anda yakin ingin mengedit data ini ?');" class="btn btn-primary" value="Edit"/>@method('PUT') </form></td>
列表查询方法(报错逻辑所在位置)
public function lihatdata(){ if(Auth::id()){ $caridata = $_GET['query']; $tanggal_dari = $_GET['tanggaldari']; $tanggal_ke = $_GET['tanggalke']; $filtersubid = dataacuan::select('subid')->whereNotNull('subid')->distinct()->get(); $data = lokasipekerjaan::when($caridata,function($caridatat,$caridata){ return $caridatat->where('cut','LIKE','%'.$caridata.'%') ->orwhere('fill','LIKE','%'.$caridata.'%') ->orwhere('mid','LIKE','%'.$caridata.'%') ->orwhere('subid','LIKE','%'.$caridata.'%') ->orwhere('lokasi','LIKE','%'.$caridata.'%') ->orwhere('id','LIKE','%'.$caridata.'%') ->orwhere('pekerjaan','LIKE','%'.$caridata.'%') ->groupby('subid')->select( DB::raw("DATE(tanggal) as tanggal"), ); })->whereDate('tanggal','>=',$tanggal_dari) ->whereDate('tanggal','<=',$tanggal_ke)->paginate(5); return view('admin.lihat_data',compact('data','caridata','filtersubid','tanggal_dari','tanggal_ke')); }else{ return view('admin.notfound'); } }
报错触发代码段:新增
DB::raw日期格式化、whereDate日期范围过滤逻辑后,关键词搜索触发SQL报错->select( DB::raw("DATE(tanggal) as tanggal"), ); })->whereDate('tanggal','>=',$tanggal_dari) ->whereDate('tanggal','<=',$tanggal_ke)
报错原因
- 核心SQL错误:关键词查询触发
when闭包逻辑时,仅查询了DATE(tanggal) as tanggal单个字段,同时使用groupBy('subid')分组,在Laravel默认开启的MySQL严格模式下,违反ONLY_FULL_GROUP_BY规则,SELECT列表字段未全部出现在group by子句中,直接抛出SQL语法错误。 - 查询逻辑错误:多个
orWhere条件未做闭包包裹,会导致外层的whereDate日期过滤条件被OR逻辑绕过,筛选结果不符合预期。 - 参数读取错误:直接通过
$_GET读取参数未做判空,对应参数缺失时会抛出未定义索引错误。 - 表单代码错误:
- 资源路由下编辑提交应指向
update路由,错误使用了editGET路由; - HTML表单原生不支持PUT方法,且代码中重复声明了请求方法;
- cut、fill、area三个字段的name属性全部误写为
volume,提交时无法读取正确字段值; - 部分输入框重复声明value属性,HTML解析异常;
- form、tr、td标签嵌套错误,DOM结构错乱。
- 资源路由下编辑提交应指向
修复方案
- 重构列表查询逻辑,移除不合理的select和groupBy,对OR条件做闭包包裹,通过Request实例读取参数并设置默认值,日期条件仅在参数存在时生效:
public function lihatdata(Request $request){ if(!Auth::id()){ return view('admin.notfound'); } // 读取参数并设置默认值,避免未定义索引报错 $caridata = $request->input('query', ''); $tanggal_dari = $request->input('tanggaldari'); $tanggal_ke = $request->input('tanggalke'); $filtersubid = dataacuan::select('subid')->whereNotNull('subid')->distinct()->get(); $data = lokasipekerjaan::query() ->when($caridata, function($query) use ($caridata){ // 所有OR查询条件包裹在闭包内,避免和外层日期过滤条件冲突 return $query->where(function($q) use ($caridata){ $q->where('cut','LIKE',"%{$caridata}%") ->orWhere('fill','LIKE',"%{$caridata}%") ->orWhere('mid','LIKE',"%{$caridata}%") ->orWhere('subid','LIKE',"%{$caridata}%") ->orWhere('lokasi','LIKE',"%{$caridata}%") ->orWhere('id','LIKE',"%{$caridata}%") ->orWhere('pekerjaan','LIKE',"%{$caridata}%"); }); }) // 日期参数存在时才添加范围过滤条件 ->when($tanggal_dari, function($q) use ($tanggal_dari){ return $q->whereDate('tanggal', '>=', $tanggal_dari); }) ->when($tanggal_ke, function($q) use ($tanggal_ke){ return $q->whereDate('tanggal', '<=', $tanggal_ke); }) ->paginate(5); return view('admin.lihat_data', compact('data','caridata','filtersubid','tanggal_dari','tanggal_ke')); }
若业务确实需要按subid分组+格式化日期字段,必须将SELECT列表中所有非聚合字段全部加入groupBy子句,不推荐通过关闭数据库ONLY_FULL_GROUP_BY模式规避错误,会导致查询结果不可控。
- 修复Blade表单错误,修正路由指向、字段name属性、标签嵌套问题:
@foreach($data as $datas) <tr class="table-info"> {{-- 资源路由更新方法为lokasipekerjaan.update,表单使用POST方法 --}} <form action="{{route('lokasipekerjaan.update', [$datas->id])}}" method="POST"> @csrf @method('PUT') <td> <input type="text" value="{{ old('id', $datas->id) }}" style="background-color: #E0FFFF;width:40px;height:40px;" name="id"> </td> <td><input type="text" value="{{ old('mid', $datas->mid) }}" style="background-color: #E0FFFF;width:40px;height:40px;" name="mid"></td> <td> <input type="text" value="{{ old('subid', $datas->subid) }}" style="background-color: #E0FFFF;width:100px;height:40px;" name="subid"> </td> <td> <input type="text" value="{{ old('pekerjaan', $datas->pekerjaan) }}" style="background-color: #E0FFFF;height:40px;" name="pekerjaan"> </td> <td> <input type="text" value="{{ old('lokasi', $datas->lokasi) }}" style="background-color: #E0FFFF;height:40px;" name="lokasi"> </td> {{-- 修正字段name属性与数据库字段对应 --}} <td> <input type="text" value="{{ old('cut', $datas->cut) }}" style="background-color: #E0FFFF;height:40px;" name="cut"> </td> <td> <input type="text" value="{{ old('fill', $datas->fill) }}" style="background-color: #E0FFFF;height:40px;" name="fill"> </td> <td> <input type="text" value="{{ old('area', $datas->area) }}" style="background-color: #E0FFFF;height:40px;" name="area"> </td> <td> <input type="text" value="{{ old('uom', $datas->uom) }}" style="background-color: #E0FFFF;width:40px;height:40px;" name="uom"> </td> <td> <input type="text" value="{{ old('tanggal', $datas->tanggal) }}" style="background-color: #E0FFFF;width:100px;height:40px;" name="tanggal"> </td> <td> <input type="submit" onclick="return confirm('apakah anda yakin ingin mengedit data ini ?');" class="btn btn-primary" value="Edit"/> </td> </form> </tr> @endforeach
内容的提问来源于stack exchange,提问作者Muhammad Bayu Kurniawan
相关产品推荐
相关产品推荐

