我在SqlException
上因违反表格上的唯一性约束而获得PreparedStatement
(欺骗密钥)。基本上我的表看起来像这样:
mytable
=======
mytable_id PRIMARY KEY INT NOT NULL
fizz_id INT NOT NULL
buzz_timestamp DATETIME
唯一性约束在buzz_timestamp
;也就是说,没有2条记录可能具有相同的日期/时间"时间戳"。
将记录插入此表的PreparedStatement
如下所示:
PreparedStatement ps = conn.prepareStatement(insertQuery);
ps.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
因此,您可以看到我正在使用java.util.Date()
("现在")并将其转换为java.sql.Date
个实例。
我看到的确切错误(欺骗密钥)一直在抱怨我试图将2015-05-27 00:00:00.0000000
插入到buzz_timestamp
的表格中,但它已经存在。所以,显然,我使用了Date API错误,并且我插入了具有无效时间组件的日期,从而产生了欺骗性密钥异常。
所以我问:我如何纠正这一点,以便我真正插入"现在"
的日期和时间答案 0 :(得分:5)
使用
ps.setTimestamp(new java.sql.Timestamp(System.currentTimeMillis());
答案 1 :(得分:2)
accepted answer是正确的。我会补充说明。
在SQL中,DATE是一个仅限日期的值,缺少时间或时区。
与Java捆绑在一起的旧日期时间类的混乱缺少任何此类来表示仅限日期的值。
相反,Java团队创建了一个hack。他们通过扩展java.util.Date创建了java.sql.Date,尽管它的名称令人困惑,但它的日期部分和是一个时间部分。对于面向SQL的子类,它们将时间部分设置为零值。你可能会认为那是“午夜”。所以java.sql.Date 有一个时间,但假装没有。
引用java.SQL.Date
doc:
为了符合SQL DATE的定义,java.sql.Date实例包含的毫秒值必须通过在特定时区中将小时,分钟,秒和毫秒设置为零来“标准化”。实例是关联的。
对于SQL中的日期和时间值,请使用accepted answer中显示的java.sql.Timestamp
类。
这些设计糟糕的日期时间类已被Java 8及更高版本中内置的新java.time包取代。这个软件包的灵感来自Joda-Time库。
Java.time包中包含表示仅限日期和仅限时间类的类。最终,JDBC驱动程序将升级为直接支持新数据类型。在此之前,使用添加到旧类和新类的几种转换方法。搜索StackOverflow.com的许多示例和讨论,因为这个问题在很大程度上是重复的。
答案 2 :(得分:1)
java.sql.Date
扩展java.util.Date
但工作方式不同:在SQL中,DATE
没有时间。因此,Java对象也会忽略小时,分钟等。
请尝试使用java.sql.Timestamp
,但您可能需要使用强制转换(在SQL中)将其转换为DATETIME
。
相关:
答案 3 :(得分:0)
您需要尝试setTimestamp
,而不是setDatejava.sql.Date - A date only (no time part)
java.sql.Time - A time only (no date part)
java.sql.Timestamp - Both date and time