【问题标题】:Can I compare resultsets like this? I'm facing the below error我可以比较这样的结果集吗?我面临以下错误
【发布时间】:2018-10-14 14:13:30
【问题描述】:

我有 2 个结果集。第一个 ResultSet 包含来自 database1 的 table1 的记录,第二个 ResultSet 包含来自 database2 的 table2 的记录。我需要一个来自resultset1 的记录列表,这些记录在resultSet2 中不存在。为此,我编写了此逻辑,但它不起作用并抛出以下错误。

java.sql.SQLException:只读结果集的无效操作:deleteRow

if ( table1ResultSet != null )
  {
    while ( table1ResultSet.next() )
    {
      final String table1Record = table1ResultSet.getString( 1 );

      if ( table2ResultSet != null )
      {
        while ( table2ResultSet.next() )
        {
          final String table2Record = table2ResultSet.getString( 1 );

          if ( table1Record.toString().equalsIgnoreCase( table2Record.toString() ) )
          {
            table1ResultSet.deleteRow();

            break;
          }
        }
      }
    }


  }

  return table1ResultSet;

【问题讨论】:

  • table1ResultSet 的第一次迭代中,您将table2ResultSet 的光标移到了最后一个结果之外。您需要将光标重置回“开始之前” - 当然,您可以只查询第二个数据库以获取 table1ResultSet 中每一行的结果
  • 你真的要从database1的table1中删除记录吗?
  • 我想要 table1 中不存在于 table2 的记录列表

标签: java loops jdbc resultset


【解决方案1】:

该异常说明了问题所在 - 您的结果集不支持删除。为了获得可更新的结果集,有一些要求:

当您准备语句时,您是否使用 ResultSet.CONCUR_UPDATABLE?

查询只能从单个表中进行选择,而无需任何连接操作。 查询必须选择所有不可为空的列和所有没有默认值的列。查询不能使用“SELECT *”。无法选择派生列或聚合,例如一组列的 SUM 或 MAX。

您可能希望在执行您正在执行的操作之前将结果集移动到 Java 集中,因为使用 deleteRow 实际上会从数据库中删除该行(除非这是预期结果)

您的代码还有另一个问题。即使删除有效,您的代码也会在结果集 1 的第二次迭代中失败,因为您从未重置 table2ResultSet,并且对于第二次迭代,table2resulset 中不会有更多结果。

但最重要的是。你为什么要经历所有这些麻烦并获得所有你不需要的行,而不是通过一个查询来完成,例如:

select * from table 1 where id not in select id from table 2

delete from table 1 where id not in select id from table 2

如果这是目标

【讨论】:

  • 这里我处理 2 个数据库。所以不能这样做。我的意图是从 table1 中获取未在 table2 中预设的记录列表。 table1 和 table2 在不同的数据库中。如果您有任何其他方法可以满足我的要求,请向我推荐
  • 好吧,我可以建议将两个结果集读入 Java 集合,然后执行该逻辑
  • 不使用集合我必须这样做。只有结果集
  • 为什么要在没有集合的情况下这样做? :) 您可以使用 getArray 方法并处理结果。您意识到无论如何您都需要一些地方来存储找到的结果吗?如果从结果集中删除,它会从数据库中删除记录?
  • 我们正在处理数百万条记录。如果我使用集合,可能会出现内存/JVM 问题。这就是我想在不使用集合的情况下实现它的原因
【解决方案2】:

你的逻辑:

  1. 假设记录按某种顺序排列(可能是也可能不是,取决于您的 SQL)
  2. 为结果集 1 的每一行消耗整个结果集 2,这不太可能是您的意图
  3. 删除东西,这也不是你在问题中提到的

您的问题可以这样轻松实现:

Set<String> list1 = new HashSet<>();
while (table1ResultSet.next())
    list1.add(table1ResultSet.getString(1).toLowerCase());

while (table2ResultSet.next())
    list1.remove(table2ResultSet.getString(1).toLowerCase());

System.out.println(list1);

这将打印出现在第一个结果集中但不在第二个结果集中的所有值(不重复)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 2010-09-22
    • 2013-01-25
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多