簡體   English   中英

Java:未使用所有查詢結果填充JDBC ResultSet

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

我正在努力使我們系統的Java Bean能夠在通過數據庫向下運行查詢時使用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在其集合中只有一行,並且該行始終對應於第一行? IN子句中的參數。

我什至嘗試用([列名] =?或[列名] =?... 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條記錄。

  • 仔細檢查完整的構造查詢,並比較它實際上是您所期望的
  • 仔細檢查您是否實際使用不同的索引值 String調用setString() ,以及是否一次又一次地使用相同的值
  • 仔細檢查一次循環迭代,您是否沒有多次調用ResultSet的next()
  • 編輯: System.out.println()並檢查(並可能發布)以下內容:
    • 完整的SQL查詢字符串
    • 新創建的PreparedStatement toString()
    • 每次調用setString() ,每個setString()調用的兩個參數和PreparedStatement toString() setString()
    • 每次調用next()的返回值

那么,您使用了這種結構嗎?

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個值這一事實外,這還行得通。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM