2016-07-26 29 views
0

我有一個SimpleJdbcCall的問題。數列中有一個空值,當我試圖通過存儲過程查詢它時,我得到了NumberFormatException。如何在Java中使用SimpleJdbcCall讀取空值,Spring?

我有了這種結構的表格:

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

聽起來像你的數據庫中的'RATING'列不是一個數字。檢查數據庫中的數據並確保其數字。 –

回答

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。以上兩項中的一項將解決您的問題,但您應該分析您的使用案例,看看實際上最適合您的是什麼。

+0

堆棧跟蹤指向它發生在JDBC驅動程序內部,而不是在獲得評級時。 –

+0

'RATING'是一個數字與OP狀態'RATING NUMBER(1,1)' – Julian

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; 
    /

我在空轉換爲BigDecimal的思維錯誤,但沒有與所有空值的任何錯誤。如預期的那樣,過程調用在列中的值爲null時返回空值。

感謝大家的幫助。

相關問題