1

我搜索了这个问题的答案,只找到了模糊的答案。这是问题所在:我在 MySQL 中有一个示例表:mytable time Timestamp data BigInt(20) unsigned

选择数据字段以便它可以接受 2^64 最大值:18446744073709551616(20 位,因此 BigInt(20))。

我有一个包含无符号 64 位整数的 csv 文件。

现在我正在使用 Java 和 JDBC 插入这些数据并遇到问题,因为 Java 没有无符号长。所以我尝试只传递字符串 - 但它失败了。

st = conn.prepareStatement("INSERT INTO pawan_table (mytime, data) VALUES(?, ?)");
st.setTimestamp(1, new Timestamp(86400000+i*1000));
st.setString(2, "18446744073709551616");
st.execute();

我还尝试了 Java 中的 BigInteger 类 - 但 JDBC 没有采用该类型的方法。我只能将 BigInteger 转换为已签名的“long”,这不是我想要的。例如:

BigInteger bi = new BigInteger(string_from_csv_file);
st.setLong(2, bi.longValue());

有趣的是,MySQL Workbench 可以插入这些数据——但它是用 c# 编写的!我需要用Java编写我的代码!

Java 程序员如何在 MySQL BigInt(20) 列中插入无符号 64 位数字?

4

3 回答 3

3

所以这里是解决方案:

如果您不使用 prepare 语句而只是使用字符串 SQL 语句插入,则无需担心,因为 JDBC 只是将您的语句移动到 MySQL 服务器,并且 MySQL 服务器可以正确地将字符串解析为无符号 64 数字 (BigInt-20)。

如果您使用准备语句,那么您就有麻烦了。如果你这样做:

BigInteger bi = new BigInteger("18446744073709551615"); // max unsigned 64-bit number
statement.setObject(2, bi, Types.BIGINT);
statement.execute();

你会得到一个 MySqlDataTruncation 异常,因为 JDBC 想要将它截断为有符号长。

如果你这样做:

BigInteger bi = new BigInteger(new Long(Long.MAX_VALUE).toString());
statement.setObject(2, bi, Types.BIGINT);
statement.execute();

这将起作用,因为该值在 Java 的有符号长整数范围内。

所以总是有效的解决方法是:

BigInteger bi = new BigInteger("18446744073709551615"); // max unsigned 64-bit number
statement.setString(2, bi.toString());
statement.execute();

您最终将数据作为字符串传递并让 MySQL 服务器正确解析它。

应该有人修复 JDBC 驱动程序,因为无符号 64 位数字在许多统计应用程序中不断出现。

于 2013-03-07T01:23:06.337 回答
0

您也许可以使用PreparedStatement.setObject. 有一个变体接受指定值类型的参数:您可以传入 aBigIntegerjava.sql.Types.BIGINT查看它是否有效。

如果失败,那么您可以创建一个辅助类来实现SQLData并将其传递给setObject.

免责声明:我没有尝试过任何这些;它基于对 javadocs 的快速浏览。

于 2013-03-06T07:43:01.557 回答
0

如果数据类型是 BIGINT UNSIGNED,这适用于 MySQL 后端。

以这种方式存储号码:

PreparedStatement statement = conn.prepareStatement("INSERT INTO Speeds (downSpeed) VALUES (?)");
statement.setObject(1, spd.downSpeed, Types.BIGINT);

使用原始 getObject() 调用进行检索:

BigInteger downSpeed = (BigInteger) rs.getObject("downSpeed");

我尝试使用rs.getObject("downSpeed",BigInteger.class),但这给了我一个不受支持的转换错误。

请注意,BIGINT UNSIGNED 类型中可以存储的最大数字是 1.8 *10^9。见这里:MySQL 数据类型

于 2015-08-26T20:59:05.573 回答