如何将Laravel 8控制器中的变量值传入MySQL存储过程使用
Laravel 变量传入MySQL存储过程解决方案
1 修改MySQL存储过程,声明接收参数
你当前的存储过程未定义入参,需要先补全所需参数声明,同时修正原有语法错误、优化查询逻辑,修改后代码如下:
CREATE PROCEDURE `home_search` ( -- 按顺序定义4个入参,分别对应城市名、搜索关键词、纬度、经度 IN p_city VARCHAR(255), IN p_search_keyword VARCHAR(255), IN p_latitude DECIMAL(10,8), IN p_longitude DECIMAL(11,8) ) BEGIN SELECT pharmacies.*, cities.*, SQRT(POW((p_latitude - pharmacy_lat ), 2) + POW((p_longitude - pharmacy_long), 2)) * 111.319 AS distance FROM pharmacies -- 补充表关联条件,避免笛卡尔集错误,关联字段可根据你的实际表结构调整 INNER JOIN cities ON pharmacies.city_id = cities.id WHERE -- 替换原有占位变量为定义的入参 cities.city = p_city AND pharmacies.city_address LIKE CONCAT('%', p_search_keyword, '%') -- 修正原有ORDER BY后的多余逗号 ORDER BY distance ASC LIMIT 3; END
如果你在MySQL命令行执行创建语句报错,可先执行
DELIMITER //修改语句结束符,创建完成后再执行DELIMITER ;恢复默认设置。
2 修改Laravel控制器代码,安全传参
原有直接拼接SQL的写法存在SQL注入风险,改用Laravel自带的参数绑定方式传参,参数顺序要和存储过程定义的入参顺序完全一致,修改后代码如下:
public function index(Request $request) { $latitude = "-6.190054983260954"; $longitude = "106.79885292237778"; $cities = City::all(); $city = $request->get('city_name'); $search = $request->get('keyword'); // 用?作为参数占位符,按存储过程入参顺序传入变量 $getDistance = DB::select('CALL home_search(?, ?, ?, ?)', [ $city, $search, $latitude, $longitude ]); return view('pages.index', [ 'getDistance' => $getDistance, ]); }
注意事项
- 存储过程的入参顺序必须和控制器中传参的顺序完全一致,否则会出现参数错位、查询结果错误的问题
- 上述代码中的表字段、关联外键均为示例,你需要根据自己的实际表结构调整对应字段名
- 经纬度使用DECIMAL类型存储和传参,可保证距离计算的精度
- 参数绑定是强制要求,可完全避免用户输入带来的SQL注入风险
内容的提问来源于stack exchange,提问作者Sutan Firqy
相关产品推荐
相关产品推荐

