gpt4 book ai didi

java - JdbcTemplate.queryForObject 无法将参数绑定(bind)到查询

转载 作者:行者123 更新时间:2023-12-02 08:20:21 24 4
gpt4 key购买 nike

我正在使用 JdbcTemplate.queryForObject(String sql, RowMapper rowMapper, Object...args) 从 Oracle 获取一行,但不断收到 EmptyResultDataAccessException 不正确的结果大小:预期 1,实际 0。

我已经使用 Oracle SQL Developer 验证了我的 SQL,它返回 1 行,就像它应该的那样。

  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);
    }
  2. 这有效。

    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);
    }
  3. 这有效。

    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);
    }
  4. 示例 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)。

我应该如何将参数绑定(bind)到这两种类型的查询上有区别吗?

Yes, there is difference!

由于 CHAR(16 BYTE) 是固定长度,并且我的 Java 字符串输入仅包含 15 个字符,因此我必须指示 Oracle 用空格填充我的输入,直到恰好达到 16 个字符。这就是 RPAD(:imsi, 16, ' ') 发挥作用的地方。

我的解决方案基于 8.3.1 CHAR, VARCHAR, and LONGVARCHARUse a CHAR field in the WHERE clause in a PreparedStatement

最佳答案

你使用的是哪个 spring 版本,因为我在 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)您应该传递参数类型的方法。

关于java - JdbcTemplate.queryForObject 无法将参数绑定(bind)到查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29895943/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com