Laravel原生查询返回空数组,phpMyAdmin执行同查询有结果
解决Laravel执行原生IN查询返回空数组的问题
这个问题我之前也碰到过,核心问题出在你对Laravel参数绑定的理解上——你把多个手机号拼成了一个字符串当作单个参数传入,这就导致SQL执行时的逻辑和你在phpMyAdmin里直接跑的不一样了。
问题根源
你拼接出来的字符串'+1234567819','+19873216154','+15984989898',当通过DB::select绑定参数时,Laravel会把它当作单个完整的值包裹在引号里,最终执行的SQL其实是:
SELECT id, reply_text, sending_time FROM sms_sender_inbox_replies WHERE phone_number IN ('\'1234567819\',\'19873216154\',\'15984989898\'') AND id IN ( SELECT MAX( id ) FROM sms_sender_inbox_replies GROUP BY phone_number )
相当于你在找一个等于'+1234567819','+19873216154','+15984989898'的手机号,自然匹配不到任何结果。
两种可行的解决方案
方案一:用Laravel查询构造器构建查询(推荐)
Laravel的查询构造器会自动处理whereIn的参数绑定,不需要手动拼接,代码更安全也更易维护:
$phone_numbers = ['+1234567819', '+19873216154', '+15984989898']; $results = DB::connection('second_connection') ->table('sms_sender_inbox_replies') ->select('id', 'reply_text', 'sending_time') ->whereIn('phone_number', $phone_numbers) ->whereIn('id', function ($subQuery) { $subQuery->selectRaw('MAX(id)') ->from('sms_sender_inbox_replies') ->groupBy('phone_number'); }) ->get();
方案二:手动生成占位符的原生SQL绑定
如果坚持用原生SQL,需要为每个手机号生成独立的占位符,再把数组作为参数传入:
$phone_numbers = ['+1234567819', '+19873216154', '+15984989898']; // 根据手机号数量生成对应数量的?占位符 $placeholders = implode(',', array_fill(0, count($phone_numbers), '?')); $sql = <<<SQL SELECT id, reply_text, sending_time FROM sms_sender_inbox_replies WHERE phone_number IN ($placeholders) AND id IN ( SELECT MAX( id ) FROM sms_sender_inbox_replies GROUP BY phone_number ) SQL; $results = DB::connection('second_connection')->select($sql, $phone_numbers);
验证效果
调整后查看查询日志,你会看到每个手机号都是单独的参数,而不是拼接成一个字符串,这样SQL逻辑就和你在phpMyAdmin里执行的完全一致,就能正确返回那3条结果了。
内容的提问来源于stack exchange,提问作者Liga
相关产品推荐
相关产品推荐

