查询Oracle数据库时出现意外的IncorrectResultSizeDataAccessException

时间:2014-12-17 12:11:56

标签: java oracle spring-jdbc jdbctemplate nvarchar

我有以下表格:

  create table INTERNATIONALIZATION (
    ID number not null unique,
    LANG char(2) not null,
    EXT_ID number not null,
    EXT_COLUMN char(32) not null,
    EXT_NAME char(32) not null,
    TRANS_VAL nvarchar2(512) not null
  );

以下代码旨在从中检索一个且只有一个结果(我100%确定该记录存在)。

public Optional<String> getTranslation(long idSkill, Locale lang, String extColumn, String extName) {
    try {
        return Optional.of(jdbcTemplate.queryForObject("select TRANS_VAL from INTERNATIONALIZATION where ext_id = ? and lang = ? and ext_column = ? and ext_name = ?", String.class, idSkill, lang.toLanguageTag(), extColumn, extName));
    } catch (IncorrectResultSizeDataAccessException ex) {
        return Optional.empty();
    }
}

问题是当我总是得到Optional.empty()时会抛出IncorrectResultSizeDataAccessException,因为没有找到记录。

当我在Oracle SQL Developer中执行此sql查询时,我得到了正确的结果。

是什么导致了这个问题?它可能与nvarchar2类型的所需列有关吗?

1 个答案:

答案 0 :(得分:0)

您可能需要验证传递给查询的参数。它们可能与您在Oracle SQL Developer中使用的不同。

对于调试,当您捕获异常时,请打印使用的值。

    try {
            return Optional.of(jdbcTemplate.queryForObject("select TRANS_VAL from INTERNATIONALIZATION where ext_id = ? and lang = ? and ext_column = ? and ext_name = ?", String.class, idSkill, lang.toLanguageTag(), extColumn, extName));
        } catch (IncorrectResultSizeDataAccessException ex) {
            return Optional.empty();
          // print idSkill, lang.toLanguageTag(), extColumn, extName here
        }

此外,当您使用CHAR列时,您必须注意比较时填充的空白区域。在使用绑定变量时,将chars与varchars进行比较时可能会出现问题。

创建一个测试表:
        SQL&GT; create table t1(c1 char(5));

    Table created.

    SQL> insert into t1 values ('A');

    1 row created.

    SQL> commit;

    Commit complete.

与文字比较,没问题:

    SQL> select count(*) from t1 where c1 = 'A'; 

      COUNT(*)
    ----------
         1

    SQL> select count(*) from t1 where c1 = 'A ';

      COUNT(*)
    ----------
         1

由于c1是char列,数据填充到左侧:

    SQL> select '<'|| c1 || '>' from t1;

    '<'||C1
    -------
    <A    >

与varchar2绑定变量

进行比较时
    SQL> var s varchar2(5)
    SQL> exec :s := 'A' ;

    PL/SQL procedure successfully completed.

    SQL> select count(*) from t1 where c1 = :s;

      COUNT(*)
    ----------
         0

数据必须相等(5个字符 - 一个字母,4个空格):

    SQL> exec :s :='A    '

    PL/SQL procedure successfully completed.

    SQL> select count(*) from t1 where c1 = :s;

      COUNT(*)
    ----------
         1

这只是一个提示,但我认为你最好使用varchar2列:

      create table INTERNATIONALIZATION (
        ID number not null unique,
        LANG varchar2(2) not null,
        EXT_ID number not null,
        EXT_COLUMN varchar2(32) not null,
        EXT_NAME varchar2(32) not null,
        TRANS_VAL nvarchar2(512) not null
      );