简体   繁体   English

Java:未使用所有查询结果填充JDBC ResultSet

[英]Java: JDBC ResultSet not populated with all query results

I'm working on getting our system's java beans to be able to use the SQL IN clause when running queries down through the database, but am running into a perplexing problem. 我正在努力使我们系统的Java Bean能够在通过数据库向下运行查询时使用SQL IN子句,但是却遇到了一个令人困惑的问题。

I am build the SQL query for the PreparedStatement in the following generic pattern: 我以以下通用模式构建PreparedStatement的SQL查询:

select [column names] 
from [table name]
where [a column name] IN (?, ? , ?, ..., ?)

The ..., represents any number of ?'s depending on the number of values the user is deciding to build into the IN clause. ...,表示任意数量的?,具体取决于用户决定在IN子句中构建的值的数量。 I run a loop to get these into the query string. 我运行一个循环,以将它们放入查询字符串中。

From here, I use the PreparedStatement's setString( idx, String ) method, and iterate through the list of values and run from index 1 - # of values. 从这里开始,我使用PreparedStatement的setString(idx,String)方法,并遍历值列表并从索引1-值#开始运行。

The PreparedStatement runs the query via the executeQuery() method and the returned ResultSet seems to be incorrect. PreparedStatement通过executeQuery()方法运行查询,并且返回的ResultSet似乎不正确。

In a specific instance using 4 values, when I take the query in the PreparedStatement to SQL and replace each ? 在使用4个值的特定实例中,当我将PreparedStatement中的查询带到SQL并替换每个吗? with the exact values in ' ', I get 3 results (as one of the values is purposely not in the DB). 使用“”中的确切值,我得到3个结果(因为其中一个值故意不在数据库中)。

The ResultSet, on the other hand only has 1 row in its set, and that row always corresponds to the first ? 另一方面,ResultSet在其集合中只有一行,并且该行始终对应于第一行? parameter in the IN clause. IN子句中的参数。

I even tried faking the IN clause with ([column name] = ? OR [column name] = ? ... OR column name] = ?) but the same issue occurs here too. 我什至尝试用([列名] =?或[列名] =?... OR列名] =?)伪造IN子句,但这里也发生相同的问题。

Any ideas what is going on here? 有什么想法吗? Connecting to an Oracle database, by the way. 顺便说一下,连接到Oracle数据库。

Logs: 日志:

2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - Preparing statement SELECT MERCHANT_ID, M_NAME, M_AUTHEN, M_ADMIN_AUTHEN, M_CONTACT_ADDR, M_PAYMENT_ADDR, M_HAS_MPROXY, M_DISABLED, M_FREETEXT, TXN_ID, M_TAX_NAME, M_TAX_RATE, MERCHANT_PARENT_ID, MERCHANT_ROOT_ID, RESERVED_1, RESERVED_2, RESERVED_3, RESERVED_4, EMAIL, LOGICAL_TYPE, CHANNEL_MASK FROM MERCHANT0 WHERE MERCHANT_ID IN (?, ?, ?, ?)  ORDER BY MERCHANT_ID
2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - Adding string  to slot 1: 6172222222
2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - Adding string  to slot 2:  6177740603
2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - Adding string  to slot 3:  6177740602
2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - Adding string  to slot 4:  6172441111
2010-02-10 11:16:28,512 DEBUG  basic.BasicCursor - scanCursor() calling... checking for next row. Current row is : 0
2010-02-10 11:16:28,512 DEBUG  basic.BasicCursor - scanCursor() called, hit
2010-02-10 11:16:28,512 DEBUG  basic.BasicCursor - scanCursor() got object 6172222222
2010-02-10 11:16:28,512 DEBUG  basic.BasicCursor - scanCursor() calling... checking for next row. Current row is : 1
2010-02-10 11:16:28,512 DEBUG  basic.BasicCursor - scanCursor() called, not hit
2010-02-10 11:16:28,505 DEBUG  basic.BasicCursor - The size of variables list = 4

EDIT: Found the issues with the PreparedStatement. 编辑:发现与PreparedStatement有关的问题。 I'll leave it as an exercise to those curious to figure it out. 我会把它留给那些好奇的人来解决。 It's visible in the log statements above. 在上面的日志语句中可见。 Unfortunately, now my problem has cascaded to some annoying proprietary code we have that limits the rows from the now expected ResultSet to displaying only 1 record anyway. 不幸的是,现在我的问题已经级联到了一些令人讨厌的专有代码上,这些代码将现在预期的ResultSet中的行限制为仅显示1条记录。 sigh

  • double-check the complete constructed query and compare that it is actually what you expect 仔细检查完整的构造查询,并比较它实际上是您所期望的
  • double-check that you actually call setString() with different values for the index and the String and that you're not using the same value over and over again 仔细检查您是否实际使用不同的索引值 String调用setString() ,以及是否一次又一次地使用相同的值
  • double-check that you're not calling next() on your ResultSet more than once per loop iteration. 仔细检查一次循环迭代,您是否没有多次调用ResultSet的next()
  • edit: System.out.println() and check (and possibly post) the following: 编辑: System.out.println()并检查(并可能发布)以下内容:
    • The complete SQL query string 完整的SQL查询字符串
    • toString() of the newly created PreparedStatement 新创建的PreparedStatement toString()
    • both parameters of each setString() call and toString() of the PreparedStatement each time you call setString() 每次调用setString() ,每个setString()调用的两个参数和PreparedStatement toString() setString()
    • the return value of next() each time you call it 每次调用next()的返回值

So, you used this construct? 那么,您使用了这种结构吗?

private static final String SQL = "SELECT * FROM MERCHANT0 WHERE MERCHANT_ID IN (%s)";

public List<Merchant> list(List<Long> ids) {
    StringBuilder placeHolders = new StringBuilder();
    for (int i = 0; i < ids.size(); i++) {
        placeHolders.append("?");
        if (i + 1 < ids.size()) {
            placeHolders.append(",");
        }
    }
    String sql = String.format(SQL, placeHolders.toString());

    // ...

    try {
        // ...

        preparedStatement = connection.prepareStatement(SQL);
        for (int i = 0; i < ids.size(); i++) {
            preparedStatement.setLong(i + 1, ids.get(i));
        }
        resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            Long id = resultSet.getLong("MERCHANT_ID");
            System.out.println(id); // Should print all of the `ids`.
        }

        // ...

Apart from the fact that Oracle has a limitation of about 1000 values inside the IN clause, this is supposed to work. 除了Oracle在IN子句中限制约1000个值这一事实外,这还行得通。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM