我搜索了这个问题的答案,但只找到了模糊的答案.这是问题所在:
我在MySQL中有一个示例表:
MYTABLE
时间时间戳
数据BigInt(20)未签名
选择数据字段以使其可以接收最大值2 ^ 64:18446744073709551616(20位数因此BigInt(20)).
现在我使用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位数?
解决方法:
所以这是解决方案:
如果您不使用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希望将此截断为signed long.
如果你这样做:
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位数字会在许多统计应用程序中出现.