Laravel执行复杂SQL CASE语句遇转义问题,求解决办法
在Laravel控制器中执行带CASE语句的SQL时解决符号转义问题
你的问题核心是写法逻辑有误,导致Laravel查询构建器错误转义了<和>,同时还有SQL语法的问题,我给你梳理下正确的解决方式:
问题分析
你之前把完整的SELECT语句塞进DB::raw里,再和users.*、user_time.*一起放到User::select()中,这相当于在SELECT列表里嵌套了另一个SELECT,本身就是语法错误;另外Laravel的查询构建器会对这类特殊字符做转义处理,最终导致SQL执行失败。
正确写法一:用查询构建器拆分逻辑
把判断营业时间的CASE逻辑作为单独的字段用DB::raw包裹,和其他字段一起选择,同时记得补全表的关联条件(之前的JOIN没写关联,会产生笛卡尔积,数据完全不对):
$getRestaurant = User::select( 'users.*', 'user_time.*', DB::raw(" CASE WHEN start_time > end_time AND (CURTIME() > start_time OR CURTIME() < end_time) THEN 'open' WHEN start_time < end_time AND (CURTIME() > start_time AND CURTIME() < end_time) THEN 'open' ELSE 'closed' END AS now_status ") )->join('user_time', 'users.id', '=', 'user_time.user_id') // 替换成你的实际关联字段 ->get();
正确写法二:直接执行原生SQL
如果更习惯写完整的SQL语句,用DB::select()直接执行原生查询,这样不会触发Laravel的自动转义,同时也要补全关联条件:
$sqlquery = " SELECT users.*, user_time.*, CASE WHEN start_time > end_time AND (CURTIME() > start_time OR CURTIME() < end_time) THEN 'open' WHEN start_time < end_time AND (CURTIME() > start_time AND CURTIME() < end_time) THEN 'open' ELSE 'closed' END AS now_status FROM users JOIN user_time ON users.id = user_time.user_id; // 必须添加关联条件 "; $getRestaurant = DB::select($sqlquery);
额外注意点
你之前用的别名NOW_open/closed包含斜杠,这在SQL里是不合法的标识符,建议改成now_status这类合法别名,或者用反引号包裹(比如`NOW_open/closed`),避免额外的语法错误。
内容的提问来源于stack exchange,提问作者user14796569
相关产品推荐
相关产品推荐

