我有以下表格:
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
类型的所需列有关吗?
答案 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
);