无法将 resultSet.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE) 与 spring jdbc DaoSupport 与 Oracle 一起使用

发布于 2024-08-17 21:49:39 字数 4127 浏览 12 评论 0 原文

我想使用可滚动的结果集,所以当我使用两行代码时:

 rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
rs.absolute(12);

在我的 DAOimpl 中,我遇到异常,请帮助解决它们,提前感谢。

 import oracle.jdbc.OracleTypes;
    import org.springframework.jdbc.core.CallableStatementCallback;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    import org.springframework.stereotype.Component;
    @Component
    public class MyDAOimpl extends JdbcDaoSupport implements
            MyDAO {

        public List<User> getList(final String where) throws Exception {

            return (List) getJdbcTemplate().execute(
                    "{call PKG_USER.getUser(?,?)}",
                    new CallableStatementCallback() {
                        public Object doInCallableStatement(CallableStatement cs)
                                throws SQLException {

                            cs.setString(1, where);
                            cs.registerOutParameter(2, OracleTypes.CURSOR);
                            cs.execute();

                            ResultSet rs = (ResultSet) cs.getObject(6);

                            rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
                            rs.absolute(12);

                            List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
                        }
                    });

        }
    }

这是例外

java.sql.SQLException: Invalid argument(s) in call: setFetchDirection
    oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
    oracle.jdbc.driver.BaseResultSet.setFetchDirection(BaseResultSet.java:128)

//////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

我更改如下,我没有得到任何结果,通常,我的程序返回 100 个用户:

return (List) getJdbcTemplate().execute(new CallableStatementCreator() {

            public CallableStatement createCallableStatement(
                    Connection connection) throws SQLException {
                return connection.prepareCall(
                        "{call PKG_USER.getUser(?,?)}",
                        ResultSet.TYPE_SCROLL_SENSITIVE,
                        ResultSet.TYPE_SCROLL_INSENSITIVE);
            }
        }, new CallableStatementCallback() {

            public Object doInCallableStatement(CallableStatement cs)
                    throws SQLException, DataAccessException {

                cs.setString(1, where);
                cs.registerOutParameter(2, OracleTypes.CURSOR);
                cs.execute();

                ResultSet rs = (ResultSet) cs.getObject(6);

                //////not run////
                rs.absolute(12);
                ////////////////

                List<User> list = new ArrayList<User>();

                while (rs.next()) 
                {   
                    List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
            }
        });

I want to use scrollable resultset, so when I use two lines of code:

 rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
rs.absolute(12);

in my DAOimpl, I get exception, plz help to solve them, thank in advance.

 import oracle.jdbc.OracleTypes;
    import org.springframework.jdbc.core.CallableStatementCallback;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    import org.springframework.stereotype.Component;
    @Component
    public class MyDAOimpl extends JdbcDaoSupport implements
            MyDAO {

        public List<User> getList(final String where) throws Exception {

            return (List) getJdbcTemplate().execute(
                    "{call PKG_USER.getUser(?,?)}",
                    new CallableStatementCallback() {
                        public Object doInCallableStatement(CallableStatement cs)
                                throws SQLException {

                            cs.setString(1, where);
                            cs.registerOutParameter(2, OracleTypes.CURSOR);
                            cs.execute();

                            ResultSet rs = (ResultSet) cs.getObject(6);

                            rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
                            rs.absolute(12);

                            List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
                        }
                    });

        }
    }

this is exception

java.sql.SQLException: Invalid argument(s) in call: setFetchDirection
    oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
    oracle.jdbc.driver.BaseResultSet.setFetchDirection(BaseResultSet.java:128)

//////////////////////////////////////////////////////////////////////////////////////////

where I change like the following, I didn't get any result, normally, my procedure return 100 users:

return (List) getJdbcTemplate().execute(new CallableStatementCreator() {

            public CallableStatement createCallableStatement(
                    Connection connection) throws SQLException {
                return connection.prepareCall(
                        "{call PKG_USER.getUser(?,?)}",
                        ResultSet.TYPE_SCROLL_SENSITIVE,
                        ResultSet.TYPE_SCROLL_INSENSITIVE);
            }
        }, new CallableStatementCallback() {

            public Object doInCallableStatement(CallableStatement cs)
                    throws SQLException, DataAccessException {

                cs.setString(1, where);
                cs.registerOutParameter(2, OracleTypes.CURSOR);
                cs.execute();

                ResultSet rs = (ResultSet) cs.getObject(6);

                //////not run////
                rs.absolute(12);
                ////////////////

                List<User> list = new ArrayList<User>();

                while (rs.next()) 
                {   
                    List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
            }
        });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朦胧时间 2024-08-24 21:49:39

首先,ResultSet.TYPE_SCROLL_SENSITIVE 是一个指示结果集类型的常量,并且肯定不是 setFetchDirection 的有效参数,它需要一个 fecth方向。引用 ResultSet#setFetchDirection(int 方向):

direction - 一个 int 指定建议的获取方向; ResultSet.FETCH_FORWARDResultSet.FETCH_REVERSEResultSet.FETCH_UNKNOWN

之一

因此出现异常和消息“调用中的参数无效: setFetchDirection”。

顺便说一句,根据 Oracle 的“JDBC 开发人员指南和参考< /a>”(所有版本均可从 http://tahiti.oracle.com/ 获得) href="http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/resltset.htm#sthref1169" rel="noreferrer">处理可滚动结果集:

预设获取方向

JDBC 2.0 标准允许
预先指定方向的能力,
称为获取方向,以供使用
在处理结果集时。这
允许 JDBC 驱动程序优化其
加工。结果集如下
指定方法:

  • void setFetchDirection(int)
    方向)抛出 SQLException
    *
    int getFetchDirection() 抛出异常
    SQLException

Oracle JDBC 驱动程序仅支持
前向预设值
,您可以
可以通过输入来指定
ResultSet.FETCH_FORWARD 静态
恒定值。

ResultSet.FETCH_REVERSE
ResultSet.FETCH_UNKNOWN 不是
支持。尝试指定它们
导致 SQL 警告,并且设置
被忽略。

Oracle Database 11g 第 2 版 JDBC 驱动程序(最终版本位于写这篇文章的时候):

可滚动的结果集
实施有以下内容
限制:

  • ScrollableResultSet 上的 setFetchDirection() 不起作用
    任何东西。

但所有这些只是一种旁注,使用 setFetchDiretion 根本不是获取可滚动结果集的方法。

要使用 Spring 的 JdbcTemplate 创建可滚动结果集,您实际上应该使用方法 执行(CallableStatementCreator csc, CallableStatementCallback 操作) 与自定义 CallableStatementCreator 实现。在此实现中,使用方法 Connection.prepareCall(String sql, int resultSetType, int resultSetConcurrency) 创建一个将生成 CallableStatement具有给定类型和并发性的 >ResultSet 对象。最后,调用 rs.absolute()。


更新: connection.prepareCall() 调用存在问题,第三个参数应该是并发类型(ResultSet.CONCUR_READ_ONLYResultSet.CONCUR_UPDATABLE)。试试这个:

            return connection.prepareCall(
                    "{call PKG_USER.getUser(?,?)}",
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);

First, ResultSet.TYPE_SCROLL_SENSITIVE is a constant indicating a result set type and is certainly not a valid argument for setFetchDirection which expects a fecth direction. Quoting the parameter section of the javadoc of ResultSet#setFetchDirection(int direction):

direction - an int specifying the suggested fetch direction; one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or ResultSet.FETCH_UNKNOWN

Hence the exception and the message "Invalid argument(s) in call: setFetchDirection".

And BTW, according to Oracle's "JDBC Developer's Guide and Reference" (all versions are available from http://tahiti.oracle.com/) in Processing a Scrollable Result Set:

Presetting the Fetch Direction

The JDBC 2.0 standard allows the
ability to pre-specify the direction,
known as the fetch direction, for use
in processing a result set. This
allows the JDBC driver to optimize its
processing. The following result set
methods are specified:

  • void setFetchDirection(int
    direction) throws SQLException
    *
    int getFetchDirection() throws
    SQLException

The Oracle JDBC drivers support only
the forward preset value
, which you
can specify by inputting the
ResultSet.FETCH_FORWARD static
constant value.

The values ResultSet.FETCH_REVERSE and
ResultSet.FETCH_UNKNOWN are not
supported. Attempting to specify them
causes a SQL warning, and the settings
are ignored.

This is also mentioned in the readme of the Oracle Database 11g Release 2 JDBC Drivers (the ultimate version at the time of writing this):

The scrollable result set
implementation has the following
limitation:

  • setFetchDirection() on ScrollableResultSet does not do
    anything.

But all this was a kind of side note, using setFetchDiretion is simply not the way to get a scrollable result set.

To create a scrollable result set with Spring's JdbcTemplate, you should actually use the method execute(CallableStatementCreator csc, CallableStatementCallback action) with a custom CallableStatementCreator implementation. In this implementation, use the method Connection.prepareCall(String sql, int resultSetType, int resultSetConcurrency) to create a CallableStatement that will produce ResultSet objects with the given type and concurrency. Finally, call rs.absolute().


UPDATE: There is a problem in the connection.prepareCall() call, the third parameter should be a concurrency type (either ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE). Try this:

            return connection.prepareCall(
                    "{call PKG_USER.getUser(?,?)}",
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);
最丧也最甜 2024-08-24 21:49:39

从 jdbc 模板获取自定义 ResultSet。 Spring 提供了一个PreparedStatementCreatorFactory,您可以从中创建PreparedStatementCreator。

PreparedStatementCreatorFactory pc = new PreparedStatementCreatorFactory(sqlQuery, , new int[] {Types.VARCHAR});//query and params Types
pc.setResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);//TYPE_SCROLL_INSENSITIVE 
pc.setUpdatableResults(false);//CONCUR_READ_ONLY

jdbcTemplate.query(pc.newPreparedStatementCreator(listOfParams),
                        myResultSetExtractor);//perform query with custom psc, process results at ResultSetExtractor

To get custom ResultSet from jdbc template. Spring has provided a PreparedStatementCreatorFactory from which you can create PreparedStatementCreator.

PreparedStatementCreatorFactory pc = new PreparedStatementCreatorFactory(sqlQuery, , new int[] {Types.VARCHAR});//query and params Types
pc.setResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);//TYPE_SCROLL_INSENSITIVE 
pc.setUpdatableResults(false);//CONCUR_READ_ONLY

jdbcTemplate.query(pc.newPreparedStatementCreator(listOfParams),
                        myResultSetExtractor);//perform query with custom psc, process results at ResultSetExtractor
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文