NamedParameterJdbcTemplate执行含SUM()的SQL报无效列名错误求助
问题原因分析与解决方法
首先,你的问题根源在于SQL中的聚合函数没有指定别名,导致JDBC ResultSet中的列名是原始的聚合函数表达式(比如SUM(PRINTEDLICNUM)),而你的RowMapper在尝试用实体类属性对应的列名(比如PRINTEDLICNUM)去取值时,找不到对应的列,从而抛出Invalid column name异常。
虽然Oracle SQL Developer可以识别无别名的聚合列并显示默认名称,但JDBC驱动对列名的处理更严格,必须明确指定别名才能正确映射。
解决步骤
1. 修改SQL语句,为聚合函数添加别名
将你的SQL修改为给聚合列指定清晰的别名,别名要和数据库列名(或你在RowMapper中使用的列名)一致:
SELECT SUM(PRINTEDLICNUM) AS PRINTEDLICNUM, SUM(PRINTEDLICCOPYNUM) AS PRINTEDLICCOPYNUM, PRIPID FROM LICENSEPRINTRECORD WHERE PRIPID IN (:pripids) GROUP BY PRIPID
注意:Oracle默认将列名存储为大写,所以别名尽量使用大写,避免大小写匹配问题。
2. 确保RowMapper使用正确的列名映射
检查你的RowMapper实现,确保在从ResultSet取值时使用的列名和SQL中的别名完全一致(大小写匹配)。示例实现如下:
new RowMapper<PreviousPrintRecords>() { @Override public PreviousPrintRecords mapRow(ResultSet rs, int rowNum) throws SQLException { PreviousPrintRecords record = new PreviousPrintRecords(); // 使用大写列名匹配Oracle的默认列名规则 record.setPrintedLicNum(rs.getInt("PRINTEDLICNUM")); record.setPrintedLicCopyNum(rs.getInt("PRINTEDLICCOPYNUM")); record.setPripId(rs.getString("PRIPID")); return record; } }
3. 验证参数传递(可选)
从错误栈可以看到,NamedParameterJdbcTemplate已经正确将:pripids转换为多个占位符(in (?, ?, ?, ?, ?, ?, ?)),说明List类型的参数传递是正常的,这部分不需要调整。
完成以上修改后,你的查询应该可以正常执行并映射到PreviousPrintRecords实体类中。
内容的提问来源于stack exchange,提问作者Jack Chan
相关产品推荐
相关产品推荐

