java.sql.SQLException: 索引中丟失 IN或OUT 參數::x

來源:互聯網
上載者:User

標籤:jdbc   oracle   preparestatement   

使用JDBC時,會有這麼一個錯誤:java.sql.SQLException: 索引中丟失 IN或OUT 參數::x

如下樣本中insertLog.execute();這行會拋出這個異常:

String logSQL = "insert into tbl_obj(id, obj, type, cont, proposer, operator, date, remark) "                       + "values(seq_tot.nextval, ?, ?, ?, ?, ?, SYSDATE, ?)";insertLog = conn.prepareStatement(logSQL);insertLog.setString(2, trace.getObj());insertLog.setString(3, trace.getType());insertLog.setString(4, trace.getCont());insertLog.setString(5, trace.getProposer());insertLog.setString(6, trace.getOperator());insertLog.setString(8, trace.getRemark());insertLog.execute();


檢索了一些文章,對於這種問題,指出的原因很多,“全形半形引起;參數過多;設定檔和資料庫欄位類型不一致;或是資料庫的索引問題等”。

根據錯誤提示,和前輩種種的碰壁,歸結為兩點:

(1) 索引是否有問題?(“索引中丟失”)

(2) 欄位賦值是否與資料庫欄位類型匹配?


對於(1)的論證,查看這張表的索引,這張表是以ID作為主鍵,沒有其他索引,因此只有一個主鍵索引,查看狀態也是VALID的,沒有錯誤:

SQL> select index_name, status from user_indexes where table_name=‘TBL_OBJ_TRACE‘;INDEX_NAME                     STATUS------------------------------ --------SYS_C0031302                   VALID


對於(2)的論證,

首先看了trace的set/get方法中對欄位類型的定義,都是String,對應庫中的欄位類型都是VARCHAR2,沒有差別。

其次再看setString,和VALUES中欄位是對應的啊。其實問題就出在這了,看下setString方法的解釋:

void java.sql.PreparedStatement.setString(int parameterIndex, String x) throws SQLExceptionSets the designated parameter to the given Java String value. The driver converts this to an SQL VARCHAR or LONGVARCHAR value (depending on the argument‘s size relative to the driver‘s limits on VARCHAR values) when it sends it to the database.Parameters:parameterIndex the first parameter is 1, the second is 2, ...x the parameter valueThrows:SQLException - if parameterIndex does not correspond to a parameter marker in the SQL statement; if a database access error occurs or this method is called on a closed PreparedStatement

可以看到第一個參數parameterIndex,參數索引,parameterIndex does not correspond to a parameter marker in the SQL statement(如果沒有對應到SQL語句中的參數標識符),則會拋出SQLException異常。

SQL語句中values(seq_tot.nextval, ?, ?, ?, ?, ?, SYSDATE, ?)的參數標識符一共6個,setString同樣是6個,但順序不對,setString中第一個參數的索引序號是要和SQL語句中是一致的,並不是SQL語句中這裡VALUES欄位的位置,而應該是SQL語句VALUES中參數標識符的序號。

改為如下格式就對了:

String logSQL = "insert into tbl_obj(id, obj, type, cont, proposer, operator, date, remark) "                       + "values(seq_tot.nextval, ?, ?, ?, ?, ?, SYSDATE, ?)";insertLog = conn.prepareStatement(logSQL);insertLog.setString(1, trace.getObj());insertLog.setString(2, trace.getType());insertLog.setString(3, trace.getCont());insertLog.setString(4, trace.getProposer());insertLog.setString(5, trace.getOperator());insertLog.setString(6, trace.getRemark());insertLog.execute();


總結:

JDBC的這個報錯,提示資訊很晦澀,但這個錯誤感覺是屬於那種碰過一次之後,基本下次就能知道錯誤的範圍,排查起來應該也比較順暢了,例如:索引是否有問題、代碼中的欄位類型和表中欄位類型是否一致、代碼中使用的參數索引和SQL語句中的參數標識符是否一致(個數、順序等)。


EOF

bisal @17JUN15

??

??

java.sql.SQLException: 索引中丟失 IN或OUT 參數::x

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.