Laravel 6调用MySQL存储过程传日期参数返回空数组问题
问题原因分析
- 存储过程参数引用错误:存储过程中误用了带
@前缀的用户变量@date_ini、@date_fin,但实际传入的是无@前缀的存储过程参数,导致WHERE子句的日期条件始终不匹配,返回空结果。 - 日期格式不兼容:Laravel传递的
01-01-2022是DD-MM-YYYY格式,而MySQL的datetime类型默认识别YYYY-MM-DD或YYYY-MM-DD HH:MM:SS格式,可能导致日期参数解析异常,无法匹配数据库中的created_at字段。 - 冗余参数未使用:存储过程定义的
client参数未在查询逻辑中引用,虽然不直接导致空结果,但不符合你提到的“仅传client时可正常运行”的业务逻辑,推测是当前代码遗漏了该参数的过滤条件。
解决步骤
1. 修正存储过程的参数引用
将存储过程中的用户变量替换为传入的参数,同时用反引号包裹关键字表名:
CREATE DEFINER=`root`@`localhost` PROCEDURE `pr_SegOrder`(`client` varchar(200), `date_ini` datetime, `date_fin` datetime) BEGIN SELECT cod,norder FROM `order` op -- 补充client过滤条件(若业务需要) WHERE op.client = client AND CAST(op.created_at AS DATE) BETWEEN date_ini AND date_fin ORDER BY op.cod ASC; END
注:
order是MySQL保留关键字,必须用反引号包裹,否则可能引发语法错误。
2. 统一Laravel端的日期格式
将DD-MM-YYYY格式转换为MySQL兼容的格式,推荐用Laravel内置的Carbon工具类处理:
use Carbon\Carbon; // 转换为MySQL可识别的datetime格式 $date_ini = Carbon::createFromFormat('d-m-Y', '01-01-2022')->toDateTimeString(); $date_fin = Carbon::createFromFormat('d-m-Y', '31-12-2022')->toDateTimeString(); // 调用存储过程 $seg = \DB::select('CALL pr_SegOrder(?,?,?)', [$client, $date_ini, $date_fin]); return $seg;
也可直接传递Carbon实例,Laravel会自动转换为适配数据库的格式:
use Carbon\Carbon; $date_ini = Carbon::createFromFormat('d-m-Y', '01-01-2022'); $date_fin = Carbon::createFromFormat('d-m-Y', '31-12-2022'); $seg = \DB::select('CALL pr_SegOrder(?,?,?)', [$client, $date_ini, $date_fin]); return $seg;
3. 验证参数传递(可选)
若仍有问题,可在存储过程中临时添加调试语句,输出接收的参数值,确认参数是否正确传入:
CREATE DEFINER=`root`@`localhost` PROCEDURE `pr_SegOrder`(`client` varchar(200), `date_ini` datetime, `date_fin` datetime) BEGIN -- 调试用,执行后查看输出 SELECT date_ini, date_fin; SELECT cod,norder FROM `order` op WHERE op.client = client AND CAST(op.created_at AS DATE) BETWEEN date_ini AND date_fin ORDER BY op.cod ASC; END
内容的提问来源于stack exchange,提问作者alan delgado
相关产品推荐
相关产品推荐

