我搜索了这个问题的答案,但只找到了模糊的答案。这是问题所在: 我在MySQL中有一个示例表: MYTABLE 时间时间戳 数据BigInt(20)无符号
选择数据字段,使其最大值为2 ^ 64:18446744073709551616(20位数,因此BigInt(20))。
我有一个包含无符号64位整数的csv文件。
现在我使用Java和JDBC来插入这些数据并遇到问题,因为Java没有unsigned long。所以我试着传递字符串 - 但它失败了。
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位数?
答案 0 :(得分: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位数字会在很多统计应用程序中出现。
答案 1 :(得分:0)
您可以使用PreparedStatement.setObject
来实现此目的。有一个变体接受指定值类型的参数:您可以传入BigInteger
和java.sql.Types.BIGINT
,看看是否有效。
如果失败,那么您可以创建一个实现SQLData
的帮助程序类,并将其传递给setObject
。
免责声明:我没有尝试过这些;它是基于javadocs的快速查看。