TYPE_SCROLL_SENSITIVE和TYPE_FORWARD_ONLY之间的区别

时间:2013-06-10 14:16:32

标签: java jdbc ibm-midrange db2-400

在AS400 / DB2数据库上运行SELECT查询时遇到一些麻烦。

当我运行以下代码时,我得到一个Exception,指出光标无效。

String jdbcURL = "jdbc:as400://10.1.2.200";
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver()); 
Properties props = new Properties();
props.setProperty("user", "tracktool"); 
props.setProperty("password", "tooltrack1"); 
con = DriverManager.getConnection(jdbcURL, props);
stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 

int count = 0;
try {
    String sql = "select * from MVXJDTALR.CSYNBR where CNNBTY='ZZ'";
    assertTrue("Select lieferte kein ResultSet.", stmt.execute(sql));
    assertTrue("Keine Results im Resultset", stmt.getResultSet().first());
    count = stmt.getResultSet().getInt("CNNBNR");
    assertTrue("ResultSet hatte falsche Anzahl Spalten", count > 0);
} catch (Exception ex) {
    ex.printStackTrace();
    fail("Konnte den aktuellen Stand von CSYNBR nicht auslesen!");
}

仅更改此行后

stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 

stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 

它完美无缺。 我在互联网上发现,它与使用它时对结果集进行的更新有关。但我没有做任何更新,也不想知道它们。我只是尝试读取一行并希望从该行中获得一个单独的值。我可以直接读取单个值而无需读取整行,但这也不起作用。

发生异常时,这是一个调用跟踪。

在例外之前记录:

Toolbox for Java - Open Source Software, JTOpen 6.0, codebase 5722-JC1 V5R4M0.6
Properties  (7481705) : access = "all".
Properties  (7481705) : block size = "32".
Properties  (7481705) : block criteria = "2".
Properties  (7481705) : date format = "".
Properties  (7481705) : date separator = "".
Properties  (7481705) : decimal separator = "".
Properties  (7481705) : errors = "basic".
Properties  (7481705) : extended dynamic = "false".
Properties  (7481705) : libraries = "".
Properties  (7481705) : naming = "sql".
Properties  (7481705) : package = "".
Properties  (7481705) : package add = "true".
Properties  (7481705) : package cache = "false".
Properties  (7481705) : package clear = "false".
Properties  (7481705) : package error = "warning".
Properties  (7481705) : package library = "".
Properties  (7481705) : password = "".
Properties  (7481705) : prefetch = "true".
Properties  (7481705) : prompt = "".
Properties  (7481705) : remarks = "system".
Properties  (7481705) : sort = "hex".
Properties  (7481705) : sort language = "ENU".
Properties  (7481705) : sort table = "".
Properties  (7481705) : sort weight = "shared".
Properties  (7481705) : time format = "".
Properties  (7481705) : time separator = "".
Properties  (7481705) : trace = "true".
Properties  (7481705) : transaction isolation = "read uncommitted".
Properties  (7481705) : translate binary = "false".
Properties  (7481705) : user = "tracktool".
Properties  (7481705) : package criteria = "default".
Properties  (7481705) : lob threshold = "32768".
Properties  (7481705) : secure = "false".
Properties  (7481705) : data truncation = "true".
Properties  (7481705) : proxy server = "".
Properties  (7481705) : secondary URL = "".
Properties  (7481705) : data compression = "true".
Properties  (7481705) : big decimal = "true".
Properties  (7481705) : thread used = "true".
Properties  (7481705) : cursor hold = "true".
Properties  (7481705) : lazy close = "false".
Properties  (7481705) : driver = "toolbox".
Properties  (7481705) : bidi string type = "".
Properties  (7481705) : key ring name = "".
Properties  (7481705) : key ring password = "".
Properties  (7481705) : full open = "false".
Properties  (7481705) : server trace = "0".
Properties  (7481705) : database name = "".
Properties  (7481705) : extended metadata = "false".
Properties  (7481705) : cursor sensitivity = "asensitive".
Properties  (7481705) : behavior override = "0".
Properties  (7481705) : package ccsid = "13488".
Properties  (7481705) : minimum divide scale = "0".
Properties  (7481705) : maximum precision = "31".
Properties  (7481705) : maximum scale = "31".
Properties  (7481705) : translate hex = "character".
Properties  (7481705) : toolbox trace = "".
Properties  (7481705) : qaqqinilib = "".
Properties  (7481705) : login timeout = "".
Properties  (7481705) : true autocommit = "false".
Properties  (7481705) : bidi implicit reordering = "true".
Properties  (7481705) : bidi numeric ordering = "false".
Properties  (7481705) : hold input locators = "true".
Properties  (7481705) : hold statements = "false".
Properties  (7481705) : rollback cursor hold = "false".
Properties  (7481705) : variable field compression = "true".
Properties  (7481705) : query optimize goal = "0".
Properties  (7481705) : keep alive = "".
Properties  (7481705) : receive buffer size = "".
Properties  (7481705) : send buffer size = "".
Properties  (7481705) : XA loosely coupled support = "0".
Properties  (7481705) : translate boolean = "true".
Properties  (7481705) : metadata source = "1".
Properties  (7481705) : query storage limit = "-1".
Properties  (7481705) : decfloat rounding mode = "half even".
Properties  (7481705) : autocommit exception = "false".
Driver AS/400 Toolbox for Java JDBC Driver (21790187) : Using IBM Toolbox for Java JDBC driver implementation.
Toolbox for Java - Open Source Software, JTOpen 6.0, codebase 5722-JC1 V5R4M0.6
JDBC Level: 30
Connection 10.1.2.200 (21576085) : Client CCSID = 13488.
Connection 10.1.2.200 (21576085) : Setting server NLV = 2929.
Connection 10.1.2.200 (21576085) : Client functional level = V5R4M01   .
Connection 10.1.2.200 (21576085) : Data compression = RLE.
Connection 10.1.2.200 (21576085) : ROWID supported = true.
Connection 10.1.2.200 (21576085) : True auto-commit supported = true.
Connection 10.1.2.200 (21576085) : 128 byte column names supported = true.
Connection 10.1.2.200 (21576085) : Maximum decimal precision = 31.
Connection 10.1.2.200 (21576085) : Maximum decimal scale = 31.
Connection 10.1.2.200 (21576085) : Minimum divide scale = 0.
Connection 10.1.2.200 (21576085) : Translate hex = character.
Connection 10.1.2.200 (21576085) : query optimize goal = 0.
Connection 10.1.2.200 (21576085) : query storage limit = -1.
Connection 10.1.2.200 (21576085) : Using extended datastreams.
Connection 10.1.2.200 (21576085) : JDBC driver major version = 7.
Connection 10.1.2.200 (21576085) : i5/OS VRM = V6R1M0.
Connection 10.1.2.200 (21576085) : Server CCSID = 37.
Connection 10.1.2.200 (21576085) : Server functional level = V6R1M00014 (14).
Connection 10.1.2.200 (21576085) : Server job identifier = 546098/QUSER/QZDASOINIT.
Properties  (7481705) : decimal separator = ".".
Properties  (7481705) : date format = "dmy".
Properties  (7481705) : date separator = ".".
Properties  (7481705) : time format = "hms".
Properties  (7481705) : time separator = ":".
Connection LR59227P (21576085)  open.
Connection LR59227P (21576085) : Auto commit = "true".
Connection LR59227P (21576085) : Read only = "false".
Connection LR59227P (21576085) : Transaction isolation = "1".
Statement STMT0001 (16678784)  open. Parent: Connection LR59227P (21576085) .
Statement STMT0001 (16678784) : Escape processing = "true".
Statement STMT0001 (16678784) : Fetch direction = "1000".
Statement STMT0001 (16678784) : Fetch size = "0".
Statement STMT0001 (16678784) : Max field size = "0".
Statement STMT0001 (16678784) : Max rows = "0".
Statement STMT0001 (16678784) : Query timeout = "0".
Statement STMT0001 (16678784) : Result set concurrency = "1007".
Statement STMT0001 (16678784) : Result set holdability = "-9999".
Statement STMT0001 (16678784) : Result set type = "1003".
Statement STMT0001 (16678784) : Behavior Override = "0".
Statement STMT0001 (16678784) : Data to correlate statement with cursor Cursor CRSR0001 (6598415) .
Statement STMT0001 (16678784) : Executing SQL Statement -->[select * from MVXJDTALR.CSYNBR where CNNBTY='ZZ'].
Statement STMT0001 (16678784) : Prepared STMT0001*, SQL Statement -->[select * from MVXJDTALR.CSYNBR where CNNBTY='ZZ'].
Cursor CRSR0001 (6598415)  open.
Cursor CRSR0001 (6598415)  closed.
ResultSet CRSR0001 (20035600)  open. Parent: Statement STMT0001 (16678784) .
ResultSet CRSR0001 (20035600) : Conncurrency = "1007".
ResultSet CRSR0001 (20035600) : Fetch direction = "1000".
ResultSet CRSR0001 (20035600) : Fetch size = "0".
ResultSet CRSR0001 (20035600) : Max rows = "0".
ResultSet CRSR0001 (20035600) : Type = "1003".
Statement STMT0001 (16678784) : Executed STMT0001*, SQL Statement --> [select * from MVXJDTALR.CSYNBR where CNNBTY='ZZ'].
Statement STMT0001 (16678784) : Update count = -1.
Statement STMT0001 (16678784) : Result set = true.
Statement STMT0001 (16678784) : Number of result sets = 0.
Statement STMT0001 (16678784) : Row count estimate = 1.

实际例外:

static method: Throwing exception, sqlState: 24000 reason: Cursor state not valid. vendor code -99999.java.sql.SQLException: Cursor state not valid.
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:389)
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:366)
        at com.ibm.as400.access.AS400JDBCResultSet.beforePositioning(AS400JDBCResultSet.java:1234)
        at com.ibm.as400.access.AS400JDBCResultSet.first(AS400JDBCResultSet.java:1343)
        at com.lr.tracktool.barcode.tests.ConnectionTest.testSQLSelectAndUpdateNew(ConnectionTest.java:389)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

    java.sql.SQLException: Cursor state not valid.
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:389)
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:366)
        at com.ibm.as400.access.AS400JDBCResultSet.beforePositioning(AS400JDBCResultSet.java:1234)
        at com.ibm.as400.access.AS400JDBCResultSet.first(AS400JDBCResultSet.java:1343)
        at com.lr.tracktool.barcode.tests.ConnectionTest.testSQLSelectAndUpdateNew(ConnectionTest.java:389)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
ResultSet CRSR0001 (20035600)  closed.
Statement STMT0001 (16678784)  closed.
Connection LR59227P (21576085)  closed.

3 个答案:

答案 0 :(得分:4)

TYPE_FORWARD_ONLY ResultSet上调用first()需要通过JDBC规范抛出SQLException :( 强调我的)

  

<强>抛出:
     SQLException - 如果发生数据库访问错误;在封闭的结果集上调用此方法或结果集类型为TYPE_FORWARD_ONLY

这正是您的代码中发生的事情。如果您想检查ResultSet是否有一行,请使用next()。保证next()适用于所有结果集类型。

答案 1 :(得分:3)

你的发现是正确的。但是,让我清楚解释为什么会发生这种情况。

根据Oracle文档:

  • TYPE_SCROLL_SENSITIVE 结果可以滚动;它的光标可以 相对于当前位置向前和向后移动,并且 它可以移动到绝对位置。结果集反映了变化 在结果集保持打开状态时对基础数据源进行。
  • TYPE_FORWARD_ONLY 无法滚动结果集;它的光标 仅从第一行之前到最后一行之后向前移动。 结果集中包含的行取决于底层的方式 数据库生成结果。也就是说,它包含行 在查询执行时或作为查询时满足查询 检索行。

这就是为什么当你改变它然后它开始工作的答案。这是因为代码没有使用executeQuery()而是使用execute()。这样做的主要原因是,只有在语句可能返回多个ResultSet对象时才应使用execute方法。我在下面提供了两个链接,其中一个是上面两个要点的来源,第二个来源是关于executeQuery()execute()的解释。

Retrieving and Modifying Values from Result Sets

JDBC Guide: Getting Started - Statement

答案 2 :(得分:0)

其实我不是从你的长篇文章中了解你的问题。但是,从您的标题我想告诉您TYPE_FORWARD_ONLYTYPE_SCROLL_SENSITIVE之间的区别。

如果选择TYPE_FORWARD_ONLY,则光标将仅向前移动。您无法向后移动,即您只能在一个轨道中读取任何一行。

如果您选择TYPE_SCROLL_SENSITIVE,那么您也可以多次反向移动。

如果您想再提问,请总结您的问题。

相关问题