【问题标题】:How to reuse PreparedStatement that depends on the result of the execution如何重用取决于执行结果的 PreparedStatement
【发布时间】:2013-09-25 04:32:24
【问题描述】:

我的目标是:

我有一个SELECT 查询,我想在一个有很多行的数据库上运行它。这个查询会产生很多结果,所以我想在 LIMIT 1000OFFSET ? 的迭代中运行它,其中 ? 将是每次迭代中处理的最后一行。

例如:

  • 获取第 1 - 1000 行
  • 获取第 1001 - 2000 行
  • 获取行 2001 - 3000
  • 获取第 3001 - 4000 行
  • ...

我正在考虑在循环中执行此操作,其中每次新迭代都会将最后一次迭代的行设置为新迭代的OFFSET(例如:OFFSET 1001OFFSET 2001 等,如上所示)。

我是使用 JDBC 的新手,所以这是正确的方法吗?如果是这样,当我必须执行 PreparedStatement 并获得每次迭代的结果时,我该如何重用它?

如果这不是正确的做法,那么正确的做法是什么?

编辑: 这是我当前的代码:

private static void import(Date from, Date to) throws Exception {

    PreparedStatement p = connect.prepareStatement(statement);
    p.setInt(1, 0);
    p.add
    ResultSet results;
    for (int i=0; i< WAVES; i++) {
        results = p.executeQuery();
        Integer lastRow = importFrom(results);
        p.setInt(1, lastRow.intValue()+1);
        results.close();
    }
    p.close();
}

编辑 2: 这是 SQL 字符串:

SELECT 
item.aitem_id, item.action_type, item.user_id, item.pid, item.pr_id, item.action_time, item.notes, item.screen, item.vid, item.lo_id,
vals.value_name, vals.simple_int_value, vals.simple_double_value, vals.simple_date_value, vals.simple_string_value,
data.version_id, data.prev_version_id
FROM mySchema.aitems item
JOIN mySchema.avalues vals ON item.aitem_id=vals.aitem_id
JOIN mySchema.adata data ON item.aitem_id=data.aitem_id
LIMIT 1000 OFFSET ?;

我修改了我的代码和 SQL 以仅使用 OFFSET 进行准备。

【问题讨论】:

  • 能否给出完整的选择声明?
  • 为什么要拆分呢?这可能比一次检索所有数据效率低。特别是如果你将它们分成 1000 个的小块。
  • 我想拆分它,因为它是一个包含实时生产数据的数据库,所以我不想影响性能。我的无限制查询将产生大约 160 万条结果。
  • 您将进行 1600 次数据库调用 - 非常低效。也许重新评估您要完成的工作是有序的。听起来像是 ETL 工作。
  • 是的,这听起来效率很低。我是直接使用 JDBC 的新手,所以你能建议我应该如何去做吗?

标签: java mysql sql prepared-statement


【解决方案1】:

您的做法是正确的,但最好添加对clearParameters() 的调用并使用try finally 块。以下是我将如何实现它

PreparedStatement p = null;
ResultSet results = null;
Integer lastRow = 0;
try
{
    p = connect.prepareStatement(statement);
    p.add

    for (int i=0; i< WAVES; i++) 
    {
        p.clearParameters();
        p.setInt(1,lastRow.intValue() + 1)
        try  // This try might not really be necessary
        {
            results = p.executeQuery();
            Integer lastRow = importFrom(results);
            p.setInt(1, lastRow.intValue()+1);
        } // Add dealing with exceptions
        finally
        {
            results.close();
        }
    }
} //Add dealing with exceptions
finally
{
    p.close();
}

【讨论】:

  • 抱歉,这是一个错字,是我的代码粘贴到这里后修改的。我解决了这个问题,但它没有解决问题。这产生了一个运行时错误,我修复了它。
  • 认为这可能是一个错字。那么您遇到的问题是什么?
  • 如果我在 DBMS 程序中执行查询,我最终获得的结果数量远远少于我获得的行数。
  • 那么这很可能与您的方法importFrom 或变量WAVES 相关
  • 我怀疑是importFrom(),所以我现在正在做一些调试。我会报告结果。这是我的 WAVES:private static final int WAVES = 200;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多