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

发布于 2024-08-21 04:05:34 字数 2241 浏览 6 评论 0原文

我正在努力让系统的 java beans 在通过数据库运行查询时能够使用 SQL IN 子句,但遇到了一个令人困惑的问题。

我按照以下通用模式为PreparedStatement 构建SQL 查询:

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

... 表示任意数量的 ?,具体取决于用户决定构建到 IN 子句中的值的数量。我运行一个循环将它们放入查询字符串中。

从这里开始,我使用PreparedStatement 的setString( idx, String ) 方法,迭代值列表并从索引1 - 值# 运行。

PreparedStatement 通过executeQuery() 方法运行查询,返回的ResultSet 似乎不正确。

在使用 4 个值的特定实例中,当我将PreparedStatement 中的查询转换为 SQL 并替换每个 ?使用“ ”中的确切值,我得到 3 个结果(因为其中一个值故意不在数据库中)。

另一方面,ResultSet 在其集合中只有 1 行,并且该行始终对应于第一个 ? IN 子句中的参数。

我什至尝试使用 ([列名称] = ? OR [列名称] = ? ... OR 列名称] = ?) 伪造 IN 子句,但这里也出现同样的问题。

有什么想法吗?顺便说一句,连接到 Oracle 数据库。

日志:

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

编辑:发现PreparedStatement 的问题。我将把它作为练习留给那些好奇的人来弄清楚。它在上面的日志语句中可见。不幸的是,现在我的问题已经涉及到一些烦人的专有代码,这些代码将现在预期的 ResultSet 中的行限制为仅显示 1 条记录。 叹息

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.

I am build the SQL query for the PreparedStatement in the following generic pattern:

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

The PreparedStatement runs the query via the executeQuery() method and the returned ResultSet seems to be incorrect.

In a specific instance using 4 values, when I take the query in the PreparedStatement to SQL and replace each ? with the exact values in ' ', I get 3 results (as one of the values is purposely not in the DB).

The ResultSet, on the other hand only has 1 row in its set, and that row always corresponds to the first ? parameter in the IN clause.

I even tried faking the IN clause with ([column name] = ? OR [column name] = ? ... OR column name] = ?) but the same issue occurs here too.

Any ideas what is going on here? Connecting to an Oracle database, by the way.

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

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

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

发布评论

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

评论(2

苍景流年 2024-08-28 04:05:34
  • 仔细检查完整构造的查询并比较它是否确实是您所期望的
  • 仔细检查您实际上是否使用不同的索引值调用 setString() 和 字符串,并且您没有一遍又一遍地使用相同的值,
  • 请仔细检查您是否在每个循环迭代中没有多次对 ResultSet 调用 next()
  • 编辑:System.out.println()并检查(并可能发布)以下内容:
    • 完整的 SQL 查询字符串
    • 新创建的 PreparedStatement

    • toString()
    • 每次调用 setString() 时的两个参数以及每次调用 setString() 时 PreparedStatementtoString() 参数< /代码>
    • 每次调用 next() 时的返回值
  • 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
  • double-check that you're not calling next() on your ResultSet more than once per loop iteration.
  • edit: System.out.println() and check (and possibly post) the following:
    • The complete SQL query string
    • toString() of the newly created PreparedStatement
    • both parameters of each setString() call and toString() of the PreparedStatement each time you call setString()
    • the return value of next() each time you call it
山田美奈子 2024-08-28 04:05:34

那么,您使用了这个构造吗?

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`.
        }

        // ...

除了 Oracle 在 IN 子句中限制大约 1000 个值这一事实之外,这应该是可行的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文