我遇到的这个问题前提是将SQLServer常用的JDBC换成JTDS造成的
=============下面是转载===========
欲流远之,必固其源泉,虽然现在有了Hibernate等工具,或许我们没太多必要关注JDBC的底层操作,但是工具会不断更新或者过时或者被淘汰,所以Java基础还是最重要的,有了深厚的JDBC功底,相信再学其它ORM都轻车熟路,不费吹灰之力。
I get java.sql.SQLException: "ResultSet may only be accessed in a forward direction"
or
"ResultSet is read only"
when using a scrollable/updateable
ResultSet
.
There are three possible causes to this (if we exclude not creating the
ResultSet
with the appropriate type and concurrency in the first place):
- The executed query must be a single SELECT statement or a call to a procedure that consists of a single SELECT statement (even a SET or PRINT will cause the resulting ResultSet to be forward only read only). This is a SQL Server limitation and there's not
much jTDS can do about it.
- The scroll insensitive/updateable combination is not supported by SQL Server, so such a
ResultSet
is automatically downgraded to scroll insensitive/read-only by the server. Use the scroll sensitive/updateable combination and it should work.
- The other possible cause is that the cursor is keyset-based and either the table you are selecting from does not have a unique primary key or that primary key is not included in your
SELECT
. See the
SQL Server Documentation on cursor types for more information.
In both cases if you call Statement.getWarnings()
right after calling
executeQuery()
you'll get a warning about the
ResultSet
being downgraded. Also, please take a look at our
ResultSet
support page for some additional information and tips.
JDK5支持用rs.updateRow()直接更新当前行,而我们习惯的用法是
PreparedStatement pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
pstmt.set.....
ResultSet rs=pstmt.executeQuery();
//更新操作
if(rs.next()){
rs.updateString("fieldName","value");
...
rs.updateRow()
}
当然,这在Microsoft的JDBC驱动里面是没有问题的,可是当你用jtds的时候,这种情况就发生变化了,且让我们来参考一下jTDS官方网上的介绍——jTDS supports the following result set types on MS SQL Server(http://jtds.sourceforge.net/resultSets.html).
JDBC Type
SQL Server Cursor Type
Server Load
Description
TYPE_FORWARD_ONLY |
Firehose cursor (direct select) when read-only |
Light |
Fast, but driver will have to read all data. Not recommended when using multiple result sets. Forward only. |
Fast forward-only (static) cursor when read-only and useCursors=true
|
Heavy |
Slower than firehose cursors (multiple fetch requests), driver doesn't have to read all data. Forward only. |
Forward-only dynamic cursor when updatable |
Heavy |
Others' updates, deletes and inserts visible. Forward only. |
TYPE_SCROLL_INSENSITIVE |
Static cursor |
Heavy |
Only works with read-only concurrency (updatable is downgraded). SQL Server generates a temporary table, so changes made by others are not visible. Scrollable. |
TYPE_SCROLL_SENSITIVE |
Keyset cursor |
Medium |
Others' updates or deletes visible, but not others' inserts. Scrollable. |
TYPE_SCROLL_SENSITIVE+1 |
Dynamic cursor |
Heavy |
Others' updates, deletes and inserts visible. Scrollable. |
jTDS supports the following result set concurrencies on MS SQL Server.
JDBC Concurrency
SQL Server Concurrency
Row Locks
Description
CONCUR_READ_ONLY |
Read only |
No |
Read-only. |
CONCUR_UPDATABLE |
Optimistic concurrency, updatable |
No |
Row integrity checked using timestamp comparison or, when not available, value comparison (except text and image fields). |
CONCUR_UPDATABLE+1 |
Pessimistic concurrency, updatable |
Yes |
Row integrity is ensured by locking rows. |
CONCUR_UPDATABLE+2 |
Optimistic concurrency, updatable |
No |
Row integrity checked using value comparison (except text and image fields). |
在这里,我们可以发现一点小小的变化,那就是jTDS的TYPE_SCROLL_INSENSITIVE只支持只读操作(Only works with read-only concurrency (updatable is downgraded)),TYPE_SCROLL_SENSITIVE支持Update操作,但不支持另外的Insert(说明:此Insert指的是新增一条空记录,并在当前记录中填值的情况),而TYPE_SCROLL_SENSITIVE+1就跟MS SQL Server JDBC驱动中的TYPE_SCROLL_INSENSITIVE功能类似了。
基于此,所以我们要将原来的语句:
pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
改成如下形式:
pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
这样,你就可以应用查询,并在结果集rs的当前行直接进行更新操作了,关于ResultSet的更新用法请参照JDK文档
我遇到的这个问题前提是将SQLServer常用的JDBC换成JTDS造成的
=============下面是转载===========
欲流远之,必固其源泉,虽然现在有了Hibernate等工具,或许我们没太多必要关注JDBC的底层操作,但是工具会不断更新或者过时或者被淘汰,所以Java基础还是最重要的,有了深厚的JDBC功底,相信再学其它ORM都轻车熟路,不费吹灰之力。
I get java.sql.SQLException: "ResultSet may only be accessed in a forward direction"
or
"ResultSet is read only"
when using a scrollable/updateable
ResultSet
.
There are three possible causes to this (if we exclude not creating the
ResultSet
with the appropriate type and concurrency in the first place):
- The executed query must be a single SELECT statement or a call to a procedure that consists of a single SELECT statement (even a SET or PRINT will cause the resulting ResultSet to be forward only read only). This is a SQL Server limitation and there's not
much jTDS can do about it.
- The scroll insensitive/updateable combination is not supported by SQL Server, so such a
ResultSet
is automatically downgraded to scroll insensitive/read-only by the server. Use the scroll sensitive/updateable combination and it should work.
- The other possible cause is that the cursor is keyset-based and either the table you are selecting from does not have a unique primary key or that primary key is not included in your
SELECT
. See the
SQL Server Documentation on cursor types for more information.
In both cases if you call Statement.getWarnings()
right after calling
executeQuery()
you'll get a warning about the
ResultSet
being downgraded. Also, please take a look at our
ResultSet
support page for some additional information and tips.
JDK5支持用rs.updateRow()直接更新当前行,而我们习惯的用法是
PreparedStatement pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
pstmt.set.....
ResultSet rs=pstmt.executeQuery();
//更新操作
if(rs.next()){
rs.updateString("fieldName","value");
...
rs.updateRow()
}
当然,这在Microsoft的JDBC驱动里面是没有问题的,可是当你用jtds的时候,这种情况就发生变化了,且让我们来参考一下jTDS官方网上的介绍——jTDS supports the following result set types on MS SQL Server(http://jtds.sourceforge.net/resultSets.html).
JDBC Type
SQL Server Cursor Type
Server Load
Description
TYPE_FORWARD_ONLY |
Firehose cursor (direct select) when read-only |
Light |
Fast, but driver will have to read all data. Not recommended when using multiple result sets. Forward only. |
Fast forward-only (static) cursor when read-only and useCursors=true
|
Heavy |
Slower than firehose cursors (multiple fetch requests), driver doesn't have to read all data. Forward only. |
Forward-only dynamic cursor when updatable |
Heavy |
Others' updates, deletes and inserts visible. Forward only. |
TYPE_SCROLL_INSENSITIVE |
Static cursor |
Heavy |
Only works with read-only concurrency (updatable is downgraded). SQL Server generates a temporary table, so changes made by others are not visible. Scrollable. |
TYPE_SCROLL_SENSITIVE |
Keyset cursor |
Medium |
Others' updates or deletes visible, but not others' inserts. Scrollable. |
TYPE_SCROLL_SENSITIVE+1 |
Dynamic cursor |
Heavy |
Others' updates, deletes and inserts visible. Scrollable. |
jTDS supports the following result set concurrencies on MS SQL Server.
JDBC Concurrency
SQL Server Concurrency
Row Locks
Description
CONCUR_READ_ONLY |
Read only |
No |
Read-only. |
CONCUR_UPDATABLE |
Optimistic concurrency, updatable |
No |
Row integrity checked using timestamp comparison or, when not available, value comparison (except text and image fields). |
CONCUR_UPDATABLE+1 |
Pessimistic concurrency, updatable |
Yes |
Row integrity is ensured by locking rows. |
CONCUR_UPDATABLE+2 |
Optimistic concurrency, updatable |
No |
Row integrity checked using value comparison (except text and image fields). |
在这里,我们可以发现一点小小的变化,那就是jTDS的TYPE_SCROLL_INSENSITIVE只支持只读操作(Only works with read-only concurrency (updatable is downgraded)),TYPE_SCROLL_SENSITIVE支持Update操作,但不支持另外的Insert(说明:此Insert指的是新增一条空记录,并在当前记录中填值的情况),而TYPE_SCROLL_SENSITIVE+1就跟MS SQL Server JDBC驱动中的TYPE_SCROLL_INSENSITIVE功能类似了。
基于此,所以我们要将原来的语句:
pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
改成如下形式:
pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
这样,你就可以应用查询,并在结果集rs的当前行直接进行更新操作了,关于ResultSet的更新用法请参照JDK文档
分享到:
相关推荐
ResultSet的用法
这是一个关于jdbc的文档。很适合于初学者
ResultSet 转为listmap
java数据库连接ResultSet
ResultSet直接在JTable显示
Unknown column 'fillMen' in 'field list' java.sql.SQLException: Operation not ...java.sql.SQLException: QueryRunner requires a DataSource to be invoked in this way, or a Connection should be passed in
但它仍不支持逆向映射 (REF CURSOR->ResultSet),因此当前版本的数据库仍然不支持 IN 和 IN OUT 参数。 在本方法指南中,我们拥有两个 Java 存储过程。Java 存储过程 getEmployees() 将 SCOTT 模式中 EMP 表的所有列...
这是一个用来教你如何使用ResultSet 获取数据对象的文档,非常使用
JAVA 版本ResultSet 转换为JAVABEAN的工具类
ResultSet.TYPE_FORWARD_ONLY:(缺省类型),ResultSet指针只允许向前移动,并且不会受到其他用户对该数据库所作更改的影响。 TYPE_SCROLL_INSENSITIVE:ResultSet指针可以前后移动,甚至可以进行特定定位,例如移...
获得结果集的字段名称,ResultSet的属性要调用ResultSetMetaData的方法
jsp 三种查询分页 resultset,hibernate ,存储过程jsp 三种查询分页 resultset,hibernate ,存储过程jsp 三种查询分页 resultset,hibernate ,存储过程jsp 三种查询分页 resultset,hibernate ,存储过程
poi根据ResultSet到处Excle源码,包含项目所需jar包,可以直接运行
resultset 变成 XML 格式输出
ResultSet转List
javaResultSet常用方法.pdf
ResultSet转化为json,json转化为List,轻松搞定
ResultSet常用方法,指针滚动,讲解很详细哦!
次类对ResultSet进行封装,可以将其转化为List,Map,BO等
ResultSet转化为Model,将从数据库中取得数据进行转化,方便对数据进行操作。