【问题标题】:What happens when the number of updated rows exceeds 2^31?当更新的行数超过 2^31 时会发生什么?
【发布时间】:2016-02-20 04:37:00
【问题描述】:

我有一些代码可能会在表中插入大量行。我目前正在使用 Spring 的JdbcTemplate.update 来执行 SQL,但我有一个顾虑。

该方法,就像它所委托的裸 JDBC 的 Statement.executeUpdate,返回一个 int,其中最大值当然是 231 = 2147483648。

那么,问题是,在这种情况下,JDBC 会做什么?返回 MAX_INTEGER,其他数字,抛出异常?或者行为可能是平台(或驱动程序)特定的?我同时支持 SQL Server(通过 jTDS)和 Oracle(通过瘦驱动程序)。

【问题讨论】:

  • 等等,你的应用程序真的会在同一个语句中插入超过 20 亿行吗?还是纯粹的理论问题?
  • 是的,在极少数情况下;从广义上讲,它是将行从一个表复制(转换)到另一个。
  • 我认为您不应该为此使用 Java。如果要将数据从一个表复制到另一个表,请使用您的数据库工具(如存储过程)。我什至无法开始意识到序列化这些数据并来回发送到数据库需要多长时间,但我想这将是巨大的(足够大以至于不再有问题,因为应用程序将在那里死掉)。
  • 仅供参考,在 Java 8 中有一个 executeLargeUpdate,它返回一个 long,但您必须确保 JDBC 驱动程序支持它。
  • 我可能给了错误的印象;数据没有流经 Java 应用程序。当您使用select 执行insert 时,所有工作都在DMBS 中完成。我很欣赏对最佳方法的关注(例如专用的 ETL 工具)。在这一点上,我主要对这种情况下的行为感兴趣。

标签: java oracle jdbc spring-jdbc jtds


【解决方案1】:

它依赖于驱动程序,因为Statement是一个必须由供应商的jdbc驱动程序实现的接口。

例如,这就是 MySQL jdbc 驱动程序内部发生的情况

public int executeUpdate(String sql) throws SQLException {
    return Util.truncateAndConvertToInt(executeLargeUpdate(sql));
}

意思是

public static int truncateAndConvertToInt(long longValue) {
    return longValue > Integer.MAX_VALUE ? Integer.MAX_VALUE : longValue < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int) longValue;
}

所以在这个特定的情况下,对于这个特定的驱动,它会返回 Integer.MAX_VALUE 并且不会抛出异常。

MySQL jdbc 驱动程序和源代码可在此处获取http://dev.mysql.com/downloads/connector/j/

【讨论】:

    【解决方案2】:

    在 JDBC 4.2(Java 8 的一部分)中,我们有:Statement 类有一个方法 executeLargeUpdate 用于执行行数超过 Integer.MAX_VALUE 的更新。

    https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html

    【讨论】:

    • 这会有所帮助...看起来 Microsoft 有一个兼容 JDBC 4.2 的驱动程序,但我没有找到适用于 Oracle 的驱动程序。
    猜你喜欢
    • 2018-10-25
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多