我有SimpleJdbcCall的问题。数字列中有一个空值,当我试图通过存储过程查询它时,我得到了NumberFormatException。
我有一个具有这种结构的表:
COLUMN_NAME DATA_TYPE
-----------------------------
USER_ID NUMBER
LOGIN VARCHAR2(30 CHAR)
PASSWORD VARCHAR2(60 BYTE)
NAME VARCHAR2(30 CHAR)
RATING NUMBER(1,1)
我正在尝试查询一条记录:
USER_ID LOGIN PASSWORD NAME RATING
----------------------------------------------------------------
1 TestLogin TestPassword TestName null
这是我的程序:
create or replace procedure get_user_by_login
(p_login in number,
p_password out varchar2,
p_name out varchar2,
p_rating out number)
as
begin
select password, name, rating
into p_password, p_name, p_rating
from users_test
where login = p_login;
end;
/
这是我的代码:
public class Main
{
public static void main(String[] args) {
User user = getUserByLogin("TestLogin");
System.out.println(user);
}
static User getUserByLogin(String login)
{
SimpleJdbcCall call = new SimpleJdbcCall(getDataSource());
call.withProcedureName("get_user_by_login");
MapSqlParameterSource in = new MapSqlParameterSource();
in.addValue("p_login", login);
call.declareParameters( new SqlOutParameter("p_password", Types.VARCHAR),
new SqlOutParameter("p_name", Types.VARCHAR),
new SqlOutParameter("p_rating", Types.NUMERIC));
Map<String, Object> out = call.execute(in);
User user = new User();
user.setLogin(login);
user.setPassword((String) out.get("p_password"));
user.setName((String) out.get("p_name"));
user.setRating((BigDecimal) out.get("p_rating"));
return user;
}
static DataSource getDataSource() {
PoolProperties poolProps = new PoolProperties();
poolProps.setUrl("jdbc:oracle:thin:@localhost:1521:testDB");
poolProps.setDriverClassName("oracle.jdbc.OracleDriver");
poolProps.setUsername("TestUser");
poolProps.setPassword("test");
poolProps.setInitialSize(5);
poolProps.setMaxActive(10);
DataSource dataSource = new DataSource();
dataSource.setPoolProperties(poolProps);
return dataSource;
}
}
这是我得到的例外:
Exception in thread "main" java.lang.NumberFormatException
at java.math.BigDecimal.<init>(BigDecimal.java:494)
at java.math.BigDecimal.<init>(BigDecimal.java:383)
at java.math.BigDecimal.<init>(BigDecimal.java:806)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9153)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8954)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9557)
at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:6090)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:249)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:364)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:150)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:213)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1077)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1135)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:405)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:365)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:198)
at com.eisima.spring.Main.getUserByLogin(Main.java:39)
at com.eisima.spring.Main.main(Main.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
答案 0 :(得分:0)
嗯,您可以通过多种方式处理这种情况,例如,尽管这不是最佳方式:
try {
user.setRating((BigDecimal) out.get("p_rating"));
} catch (NumberFormatException e) {
e.printStackTrace();
}
或者也许:
if (out.get("p_rating") == null) {
user.setRating(new BigDecimal(0));
}
但是如果你试图设置一个空值,你应该期待NumberFormatException
。上面两个中的一个将解决您的问题,但您应该分析您的用例,看看哪些对您来说最合适。
答案 1 :(得分:0)
原因是程序声明不正确:
create or replace procedure get_user_by_login
-- i'm passing string there ---> (p_login in number,
p_password out varchar2,
p_name out varchar2,
p_rating out number)
as
begin
select password, name, rating
into p_password, p_name, p_rating
from users
where login = p_login;
end;
/
我在考虑将null转换为BigDecimal时出错,但根本没有任何null值的错误。正如预期的那样,过程调用在列中的值为null时返回空值。
感谢大家的帮助。