我正在使用JdbcTemplate.queryForObject(String sql,RowMapper rowMapper,Object ... args)从Oracle获取一行但不断获取EmptyResultDataAccessException结果大小不正确:预期为1,实际为0.
我已经使用Oracle SQL Developer验证了我的SQL,它就像它应该的那样返回1行。
这一直在失败。
public NgsRecord getUserInfoByImsi(String imsi) throws SQLException {
String sql = "SELECT snb, timestamp_, user_type, real_exch, act_exch, dev_type, rc FROM port WHERE imsi = ?";
RowMapper<NgsRecord> mapper = new RowMapper<NgsRecord>() {
public NgsRecord mapRow(ResultSet rs, int rowNum)
throws SQLException {
NgsRecord ngsRecord = new NgsRecord();
ngsRecord.setTimestamp(rs.getDate("timestamp_"));
ngsRecord.setUser_type(rs.getString("user_type"));
ngsRecord.setReal_exch(rs.getString("real_exch"));
ngsRecord.setAct_exch(rs.getString("act_exch"));
ngsRecord.setDev_type(rs.getString("dev_type"));
ngsRecord.setRc(rs.getString("rc"));
ngsRecord.setSnb(rs.getString("snb"));
return ngsRecord;
}
};
return this.jdbcTemplate.queryForObject(sql, mapper, imsi);
}
这样做。
public NgsRecord getUserInfoByImsi(String imsi) throws SQLException {
String sql = "SELECT snb, timestamp_, user_type, real_exch, act_exch, dev_type, rc FROM port WHERE imsi = '" + imsi + "'";
RowMapper<NgsRecord> mapper = new RowMapper<NgsRecord>() {
public NgsRecord mapRow(ResultSet rs, int rowNum)
throws SQLException {
NgsRecord ngsRecord = new NgsRecord();
ngsRecord.setTimestamp(rs.getDate("timestamp_"));
ngsRecord.setUser_type(rs.getString("user_type"));
ngsRecord.setReal_exch(rs.getString("real_exch"));
ngsRecord.setAct_exch(rs.getString("act_exch"));
ngsRecord.setDev_type(rs.getString("dev_type"));
ngsRecord.setRc(rs.getString("rc"));
ngsRecord.setSnb(rs.getString("snb"));
return ngsRecord;
}
};
return this.jdbcTemplate.queryForObject(sql, mapper);
}
这样做。
public NgsRecord getUserInfo(String snb) throws SQLException {
String sql = "SELECT snb, timestamp_, user_type, real_exch, act_exch, dev_type, rc FROM port WHERE snb = ?";
RowMapper<NgsRecord> mapper = new RowMapper<NgsRecord>() {
public NgsRecord mapRow(ResultSet rs, int rowNum)
throws SQLException {
NgsRecord ngsRecord = new NgsRecord();
ngsRecord.setTimestamp(rs.getDate("timestamp_"));
ngsRecord.setUser_type(rs.getString("user_type"));
ngsRecord.setReal_exch(rs.getString("real_exch"));
ngsRecord.setAct_exch(rs.getString("act_exch"));
ngsRecord.setDev_type(rs.getString("dev_type"));
ngsRecord.setRc(rs.getString("rc"));
ngsRecord.setSnb(rs.getString("snb"));
return ngsRecord;
}
};
return this.jdbcTemplate.queryForObject(sql, mapper, snb);
}
样本1已更新并正常工作。
public NgsRecord getUserInfoByImsi(String imsi) throws SQLException {
SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("imsi", imsi);
String sql = "/*+ INDEX(NGS.PORT IDX_PORT_IMSI) */ SELECT snb, timestamp_, user_type, real_exch, act_exch, dev_type, rc FROM port WHERE imsi = RPAD(:imsi, 16, ' ')";
return (NgsRecord) namedParameterJdbcTemplate.queryForObject(sql, namedParameters, new NgsRecordRowMapper());
}
代码示例1和3的唯一区别是imsi和snb的Oracle数据类型。 Imsi是CHAR(16 BYTE),snb是VARCHAR2(18 BYTE)。
我应该如何将参数绑定到这两种类型的查询?
是的,有区别!
由于CHAR(16 BYTE)是固定长度而我的Java String输入只包含15个字符,因此我必须指示Oracle用空格填充输入,直到它正好是16个字符。这就是 RPAD(:imsi,16,'')的用武之地。
我的解决方案基于8.3.1 CHAR, VARCHAR, and LONGVARCHAR和Use a CHAR field in the WHERE clause in a PreparedStatement
答案 0 :(得分:0)
您正在使用哪个春季版本,因为我找不到匹配的jdbcTemplate
中的方法
ueryForObject(String sql, RowMapper rowMapper,Object[] args)
你可以参考URL
我只能在下面找到三个带有rowMapper的重载方法
queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) ;
queryForObject(String sql, Object[] args, RowMapper rowMapper) ;
queryForObject(String sql, RowMapper rowMapper) ;
看着你的问题,我建议你使用
queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)
方法,您应该传递参数类型。