问题:首先我得到了一个结果集rs,遍历了一遍,之后又把游标移动first位置,重新遍历,则报以下错误:
异常信息打印:
java.sql.SQLException: 对只转发结果集的无效操作: first
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.BaseResultSet.first(BaseResultSet.java:74)
at com.yst.dal.hpstjnl.HpstjnlCheckedService.getDatails2(HpstjnlCheckedService.java:210)
at com.yst.dal.hpstjnl.HpstjnlCheckedService.main(HpstjnlCheckedService.java:340)
解决:
把preprepareStatemen修改成:
pstm = con.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
原因:缺省情况下创建的ResultSet 是一种只能访问一次(one-time-through),只能向前访问(forward-only),只读的对象。您只能访问数据一次,如果再次需要该数据,必须重新查询数据库。所以如果要再次查询,则需要设置resultSet的属性。
知识点详解:
有兴趣的可以看着个:http://blog.csdn.net/lu8000/article/details/44235951,讲得很详细
ResultSet中保存了 query查询语句执行的结果,因此被用来扫描(检索,定位)数据。不过,也可以用来导航数据和进行个别的更新。接下来我们来看下细节:
一、导航 ResultSet数据
只要数据库允许这些操作,JDBC提供了下面几个方法都可以用来导航ResultSet中数据。
ResultSet’s Methods for Navigating Rows
boolean next();
boolean previous();
boolean first();
boolean last();
void beforeFirst();
void afterLast();
boolean relative(int n);
boolean absolute(int n);
boolean next()游标位置后移一个,如果当前是最后一行了,那么返回false
boolean previous()游标位置前移一个,如果当前是第一行,则返回false
oolean first() 游标位置返回第一行,如果不存在(查询结果为空),那么返回false
boolean last()游标位置返回最后一行,如果不存在(查询结果为空),那么返回fals
void beforeFirst()返回到最开始,它的下一行是第一行数据。
void afterLast()返回到最后,它的上一行是最后一行数据
boolean relative(int n) 以当前位置为基准,跳n个位置,如果n为正那么往后移动n行,如果为负那往前移动n行。
boolean absolute(int n)为正,则以第一行为基准,跳到第n行,为负,则从最后一行往前跳n行.
二、ResultSet的三种类型参数
缺省情况下创建的ResultSet 是一种只能访问一次(one-time-through),只能向前访问(forward-only),只读的对象。您只能访问数据一次,如果再次需要该数据,必须重新查询数据库。
ResultSet.TYPE_SCROLL_SENSITIVE
双向滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据。允许在记录中定位。这种类型受到其他用户所作更改的影响。如果用户在执行完查询之后删除一个记录,那个记录将从 ResultSet 中消失。类似的,对数据值的更改也将反映在 ResultSet 中。(其它人对记录的修改会反应到你打开的记录集 敏感)
ResultSet.TYPE_SCROLL_INSENSITIVE
双向滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来。允许在列表中向前或向后移动,甚至可以进行特定定位,例如移至列表中的第四个记录或者从当前位置向后移动两个记录。不会受到其他用户对该数据库所作更改的影响。(其它人对记录的修改不会反应到你打开的记录集 不敏感)
TYPE_FORWORD_ONLY
只可向前滚动。缺省类型,不会受到其他用户对该数据库所作更改的影响。只允许向前访问一次,并且不会受到其他用户对该数据库所作更改的影响。
.
三、ResultSet 和事务处理参数
ResultSet 一般会被关闭,在事务的commit 或者 rollback被执行后.但是有时候你要保留ResultSet继续被使用怎么办?看下面参数:
HOLD_CURSORS_OVER_COMMIT: ResultSet的数据仍然可以被存取在commit 或者 rollback之后.
CLOSE_CURSORS_AT_COMMIT: ResultSet的数据被抛弃在 commits 或者 rollbacks执行后.
四、 并发性参数
ResultSet 的数据可以被更新的,为了达到这个目的要做的一件事情就是和数据库保持连接,然后就是使用一些锁机制在更新期间保护数据。并发等级参数有下面两个:
CONCUR_READ_ONLY: 不允许更新
CONCUR_UPDATABLE: 允许并发同步更新数据