java.sql.SQLException: 索引中丢失 IN或OUT 参数::x

使用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 SQLException

Sets 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 value
Throws:
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





时间: 2024-07-31 02:31:53

java.sql.SQLException: 索引中丢失 IN或OUT 参数::x的相关文章

java.sql.SQLException: 无效的列索引的问题

问题描述 publicList<RegionDomain>getRegionList2(AdministratorDomainuser){Stringsql2="select*fromwm_em_broadband_jidetailwhere1=1";StringBuffersql=newStringBuffer(sql2);inti=0;Object[]ob=newObject[6];if(user.getAccount()!=null&&!"&

求教关于“java.sql.SQLException 列名无效”的问题

问题描述 使用DBUtil查询数据库时Java报列名'lei_xing'无效.但是这个SQL语句在MSSQL的控制台下面能够争取执行.到底是什么原因啊?这是查询部分的代码:Stringsql="selecttg.fid,tg.intime,tg.lei_bie,tg.ftitle,tg.inpart,tg.inname,jl.idfromtonggaotgleftjoin(selectid,fidfromyue_du_ji_luywherelei_xing=?)jlontg.fid=jl.fid

Caused by: java.sql.SQLException: ORA-01861: 文字与格式字符串不匹配

          项目中遇到这样一个问题:                 Caused by:java.sql.SQLException: ORA-01861: 文字与格式字符串不匹配 atoracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) atoracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) atoracle.jdbc.

hibernate proxool java.sql.SQLException

问题描述 大家好,我现在在项目中使用了hibernate来连接数据库,使用到的连接池是proxool,但奇怪的是,在tomcat的日志中,每隔一定时间就会出现以下信息:09:02:35,768 DEBUG fm_oracleproxool:431 - 009441 (00/09/00) - #7920 removed because it has problems: java.sql.SQLException: ORA-00923: 未找到要求的 FROM 关键字09:02:36,407 DEB

java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]用户

问题描述 java.sql.SQLException:[Microsoft][SQLServer2000DriverforJDBC][SQLServer]用户'sa'登录失败.这是连接数据库的代码:packagedatabase;importjava.sql.*;publicclassConnectionDB{publicstaticConnectiongetConnection(){Connectionconn=null;Stringurl="jdbc:sqlserver://localhos

java.sql.SQLException: 列名无效 [问题点数:25分,结帖人zshzyh] 收藏

问题描述 java.sql.SQLException:列名无效atoracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)atoracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)atoracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.

java.sql.SQLException: Access denied for user &amp;amp;#x27;root&amp;amp;#x27;@&amp;amp;#x27;localhost&amp;amp;#x27; (using password

问题描述 连接MySql数据库,出现java.sql.SQLException:Accessdeniedforuser'root'@'localhost'(usingpassword:YES)的问题,用户名是root,密码是123456,这是我自己设置的密码,为什么连接失败呢???我在MySql中的可视化软件中,测试连接,连接成功,可是为什么在Javaweb中连接数据库不成功呢????比较急!!求解!! 解决方案 本帖最后由 PsMuJIngHua 于 2013-02-02 07:51:44 编

java.sql.SQLException错误

问题描述 运行StuDialog.class出现下面错误提示,初学Java请求帮助找出下面是什么原因?java.sql.SQLException: No value specified for parameter 2at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)at com.mysql.

spring-Could not obtain connection metadata java.sql.SQLException: Io exception

问题描述 Could not obtain connection metadata java.sql.SQLException: Io exception 启动tomcat的时候就报下面的错.求大神指引....... 谢谢 [INFO] - Initializing connection provider: org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider 2013-07-08 16:2