代码之家  ›  专栏  ›  技术社区  ›  Kannan Ekanath

JDBC批量更新问题

  •  8
  • Kannan Ekanath  · 技术社区  · 15 年前

    对于Java JDBC API和Oracle数据库,我有一个稍微独特的要求。我将autocommit设置为默认值,这对于Oracle是正确的,我使用的示例与此类似 link .

    但是,当我添加1000个批次时,假设每个批次都是插入的。让我们假设大约20条记录违反了一些约束,我希望剩下的980条被提交到数据库(并且从此以后对任何其他使用其他连接的查询都可见),而忽略20条记录。在上面的示例中,当一行违反任何事务时, 即使我在catch块中提交,事务也只提交到第一次失败为止。 .

    我知道只有当您相当确定所有的行都将经历并且异常处理不是一个时,才能进行批更新,但是我计划修补现有的数据库,这样一些“坏做法”就可以了:)任何代码示例都将受到高度赞赏。

    ****更多详细信息****

    使用简单的插入/更新是不好的,因为我正在处理近3米的行,所以每1000条记录就进行批处理。与批更新<300ms相比,在循环中添加1000个插入(忽略异常)需要更多的时间(每1000个记录大约5秒)。

    问题: 对于Oracle数据库,驱动程序似乎在第一次失败时停止,即当1000行被批处理,第100行失败时,我希望它继续执行到第1000行。我认为在JDBC(和Oracle)中不能这样做 链接 表示只有少数数据库支持此类功能,可能Oracle不是其中之一。

    7 回复  |  直到 12 年前
        1
  •  3
  •   Martlark    15 年前

    您可以使用save exceptions子句使用pl/sql存储过程,该子句允许您发出批量更新,然后返回那些无法更新的行。下面是几个示例链接:

    http://rwijk.blogspot.com/2007/11/save-exceptions.html

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8912264456901

        2
  •  2
  •   Thilo    15 年前

    您应该插入到一个没有约束的工作表中,然后删除或修复将违反的内容,并在一条SQL语句中插入select-over到实际表中。

        3
  •  1
  •   Erich Kitzmueller    15 年前

    你可以试试这个:从50或100个批次开始。(选择一个大小,这样它们就有很好的可能被成功处理)。那些失败的,逐一处理。

    其他可能性:禁用约束,加载数据,删除那些违反约束的行。

        4
  •  1
  •   Salandur    15 年前

    我应该首先检查是否有违反约束的情况,如果没有违反约束,则插入该记录。

        5
  •  1
  •   Kannan Ekanath    15 年前

    我在“使用Oracle数据库,驱动程序似乎在第一次失败时就停止了,也就是说,当1000行被成批处理,第100次失败时,我希望它继续运行到第1000行。”基本上我想知道这是否可以用Oracle JDBC驱动程序来完成。

    然而,已经提出了各种各样的答案(大部分/全部我已经考虑过了) 1)禁用约束/加载数据/删除有问题的行/重复多次 2)加载数据前进行所有检查 3)将批量缩小到50-100。

    不幸的是,我的检查不能在装载之前完成,而使批量大小为50或100意味着要花更多的时间来完成我拥有的5米行(事实上,总时间增加到几个小时,而不是40分钟,批量大小为1000)。我已设法使批量保持在1000。 照旧接受问题 并将代码置于“while”循环下,然后执行该操作,直到填满所有行。

    就像我说的,因为 无法使用Oracle批量JDBC 要在第一次失败后继续,此问题的答案将是“不可行”,只需接受约束并记录此工具大约需要40分钟才能完成的事实:)

        6
  •  1
  •   russoue    12 年前

    当语句不匹配时,可以尝试Oracle合并吗?例子: http://www.idevelopment.info/data/Oracle/DBA_tips/SQL/SQL_14.shtml

        7
  •  0
  •   user2091897    12 年前

    有一个异常表,并确保您的过程从不引发异常,而是将所有异常保存在数据库中。完成所有操作后,查询异常表和SEE记录将无法进行。