1

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

当我运行以下代码时,我得到一个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); 

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

这是发生异常时的调用跟踪。

异常前的日志记录:

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.
4

3 回答 3

5

JDBC 规范要求调用first()aTYPE_FORWARD_ONLY ResultSet来抛出 an SQLException:(强调我的)

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

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

于 2013-06-10T16:58:33.683 回答
3

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

根据 Oracle 文档:

  • TYPE_SCROLL_SENSITIVE结果可以滚动;它的光标可以相对于当前位置前后移动,并且可以移动到绝对位置。结果集反映了在结果集保持打开状态时对基础数据源所做的更改。
  • TYPE_FORWARD_ONLY结果集不能滚动;它的光标只向前移动,从第一行之前到最后一行之后。结果集中包含的行取决于底层数据库如何生成结果。也就是说,它包含在执行查询时或检索行时满足查询的行。

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

从结果集中检索和修改值

JDBC 指南:入门 - 语句

于 2013-06-10T15:10:51.153 回答
0

实际上,我从您的长篇文章中无法理解您的问题。TYPE_FORWARD_ONLY但是从您的标题中,我想告诉您和之间的区别TYPE_SCROLL_SENSITIVE

如果您选择TYPE_FORWARD_ONLY,那么您的光标将仅向前移动。您不能向后移动,即您只能在一个轨道中读取任何行一次。

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

如果您想问更多,请总结您的查询。

于 2013-06-10T15:01:46.900 回答