You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Spring JPA调用MySQL存储过程报SQL Error 1064错误解决方案求助

问题根源

你写的存储过程调用SQL语法错误,MySQL存储过程的标准调用格式是CALL 存储过程名(参数1, 参数2, ...),你在@Query注解中错误的将两个参数用括号分别包裹,生成的实际执行SQL为CALL FindAllAccountsNames (36), ('customer'),MySQL解析到第一个参数括号结束时就判定存储过程调用已经结束,后续的, ('customer')属于非法语法,和你收到的报错提示完全匹配。

修复方案

1. 修正Repository层代码

直接修改@Query注解中的调用语句,将两个参数放到同一对括号内即可:

@Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
    @Query(value = "CALL FindAllAccountsNames(:uid, :accType)", nativeQuery = true)
    List<String> findAllAccountsNames(@Param("uid") int uid, @Param("accType") String accType);
}

2. 补充存储过程安全校验(推荐)

你当前存储过程中直接将传入的accType作为表名拼接动态SQL,如果该参数由用户端传入会存在严重的SQL注入风险,建议增加合法表名校验:

DELIMITER $$
CREATE PROCEDURE `FindAllAccountsNames` (in `uid` int, in `accType` varchar(16))
BEGIN
    -- 仅允许指定的表名被查询,根据你的业务实际支持的账户类型调整IN内的值
    IF accType NOT IN ('customer', 'supplier', 'asset', 'liability', 'equity', 'income', 'expense') THEN
        SELECT -1;
    ELSEIF NOT EXISTS (SELECT `user`.`id` FROM `user` WHERE `user`.`id` = `uid`) THEN
        SELECT -1;
    ELSE 
        SET @accNames = CONCAT('SELECT `name` FROM ', accType);
        PREPARE stmt FROM @accNames;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    END IF;
END$$
DELIMITER ;
效果验证

修改完成后重新调用接口,即可正常返回对应账户类型的名称列表,和你在MySQL Workbench中本地测试的结果一致。

内容的提问来源于stack exchange,提问作者Anser Waseem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 10:09:02