存储过程调用异常:DBeaver可返回结果,代码调用返回空
问题分析与解决方案
1. 最直接的错误:参数名称不匹配
你的Java代码中传入的日期参数名称与@NamedStoredProcedureQuery注解中定义的参数名不一致:
- 代码中使用:
START_DATE、END_DATE - 注解中定义的参数名:
CREATED_START_DATE、CREATED_END_DATE
这会导致存储过程无法接收到正确的日期参数,进而过滤条件未按预期生效,最终返回空结果。
修复代码:
procedurequery = entityManager.createNamedStoredProcedureQuery("UserManagementUsersReportModel.generate"); // 修正参数名称与注解一致 procedurequery.setParameter("CREATED_START_DATE", formattedStartDate); procedurequery.setParameter("CREATED_END_DATE", formattedEndDate); procedurequery.setParameter("DEF", parameters.get("def")); procedurequery.setParameter("ABC", parameters.get("abc")); List<Report> ReportList = procedurequery.getResultList();
2. 存储过程动态SQL的潜在问题
从你提供的存储过程代码来看,存在两个风险点:
(1)WHERE子句语法错误
当只有ABC参数有值、DEF参数为null时,拼接后的SQL会出现WHERE AND cau.abc IN (...)的语法错误;同理,如果日期参数未处理,也可能导致类似问题。
修复动态SQL拼接逻辑:
使用标志位判断是否已添加WHERE条件,避免语法错误:
SET @SqlQuery = 'SELECT ulv.*, cau.CREATED_BY, cau.CREATED_DATE from CORE.DEF ulv left join CORE.ABC cau on cau.id = ulv.id'; SET @hasWhere = 0; -- 处理日期参数(假设存储过程需要使用这两个参数过滤) IF @CREATED_START_DATE IS NOT NULL AND @CREATED_END_DATE IS NOT NULL BEGIN SET @SqlQuery = @SqlQuery + ' WHERE ulv.created_date BETWEEN ''' + @CREATED_START_DATE + ''' AND ''' + @CREATED_END_DATE + ''''; SET @hasWhere = 1; END IF @DEF IS NOT NULL BEGIN IF @hasWhere = 1 SET @SqlQuery = @SqlQuery + ' AND'; ELSE SET @SqlQuery = @SqlQuery + ' WHERE'; SET @SqlQuery = @SqlQuery + ' ulv.id IN (' + @DEF + ')'; -- REPLACE操作无意义,可直接拼接 SET @hasWhere = 1; END IF @ABC IS NOT NULL BEGIN IF @hasWhere = 1 SET @SqlQuery = @SqlQuery + ' AND'; ELSE SET @SqlQuery = @SqlQuery + ' WHERE'; SET @SqlQuery = @SqlQuery + ' cau.abc IN (' + @ABC + ')'; SET @hasWhere = 1; END -- 执行拼接后的SQL(确保有这一步) EXEC sp_executesql @SqlQuery;
(2)多余的REPLACE操作
你代码中的REPLACE(@DEF, ',', ',')完全没有作用,直接使用@DEF即可。
3. 其他验证点
- 确认存储过程中确实执行了拼接后的动态SQL(比如添加
EXEC sp_executesql @SqlQuery;或对应数据库的执行命令)。 - 验证日期格式的兼容性:虽然你说参数值与DBeaver一致,但可尝试将日期转换为数据库标准格式(如
YYYY-MM-DD)传入,避免因数据库区域设置导致的解析差异。
内容的提问来源于stack exchange,提问作者Wajih Haider
相关产品推荐
相关产品推荐

