[英]Convert String into TIMESTAMP for insert into Database oracle from servlet java
[英]Oracle - How can i insert timestamp from Java Project as String without formatting
在 spring 项目中,有一个 sql 数据将值插入到 oracle 数据库中。 如果我尝试插入时间戳,我会收到 ORA-Exception(无效月份)。
INSERT INTO TAB (colTimestamp)
VALUES ('2020-05-07-10.05.05.301011')
为什么那不是一个有效月份?
在 DB2 中没有问题。 那么我应该以哪种格式插入时间戳? 我也试过2019-05-05 10:10:10但我得到了同样的异常 如何插入时间戳? oracle 中时间戳的默认格式是什么?
您需要使用使用 ISO 格式格式化的正确时间戳文字:
timestamp '2020-05-07 10:05:05.301011'
所以没有-
在日期和时间之间,和:
分隔小时、分钟和秒。 我相信同样适用于 DB2。
如果您通过 JDBC 进行插入,则不应以字符串开头。 使用PreparedStatement
并传递java.time.LocalDateTime
或至少java.sql.Timestamp
的实例
a_horse_with_no_name的答案是正确的。 这里有更多的细节和例子。
您的输入字符串不符合以下两个条件:
T
分隔日期和时间)相比之下,您的输入字符串中间有一个连字符,并且无法使用冒号字符来分隔小时-分钟-秒。
当java.time解析或生成字符串时,默认使用 ISO 8601 格式。
String input = "2020-05-07T10:05:05.301011" ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
对于在 Java 中工作,您应该在准备好的语句中将对象作为占位符的值而不是作为String
对象中的文本传递。
String sql = "INSERT INTO some_table ( some_timestamp ) VALUES ( ? ) ;" ;
myPreparedStatement.setObject( 1 , ldt ) ;
如果您坚持使用纯文本而不是对象,请对日期时间输入使用 SQL 格式。 我会简单地采用java.time 中默认生成的 ISO 8601 输出并将T
替换为空格。
String sql = String sql = "INSERT INTO some_table ( some_timestamp ) VALUES ( " + ldt.toString().replace( "T" , " " ) + " ) ;" ;
或者,您可以使用DateTimeFormatter
对象生成该文本。 搜索堆栈溢出,因为它已经被多次覆盖。
您的代码中还有另一个关键问题。 您对“时间戳”一词的使用表明您正在尝试跟踪某个时刻,即时间轴上的特定点。 您的输入字符串无法做到这一点。 您的输入缺少UTC 偏移量(本初子午线之前/之后的时分秒数)或时区( Continent/Region
格式的名称)的上下文。
以您输入的 10 AM 为例。 我们无法知道您是指日本东京的上午 10 点还是美国俄亥俄州托莱多的上午 10 点,这两个非常不同的时刻相隔许多小时。
如果您要跟踪时刻,则必须使用:
TIMESTAMP WITH TIME ZONE
数据库列。Instant
、 OffsetDateTime
或ZonedDateTime
(JDBC 4.2 中只需要支持OffsetDateTime
)。例子:
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC ) ; // Capture the current moment in UTC.
要将时刻表示为文本,您应该使用 ISO 8601 格式以Z
(对于 UTC,偏移量为零)、偏移量(例如+05:30
)或偏移量后跟方括号中的时区名称. 最后一个是java.time.ZonedDateTime
类使用的 ISO 8601 的非标准扩展。
Instant instant = Instant.parse( "2020-05-07T10:05:05.301011Z" ) ;
JDBC 4.2 需要支持OffsetDateTime
而不是Instant
。 您的 JDBC 驱动程序可能支持Instant
,但如果不支持,请转换。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
跟踪时刻时,切勿使用类似于 SQL 标准类型TIMESTAMP WITHOUT TIME ZONE
的数据库类型。 并且永远不要使用 Java 类LocalDateTime
片刻。 两者都故意缺少时区或UTC偏移量的上下文。
请遵循 ISO 日期格式,以便 Oracle 接受它作为日期。
例1:
INSERT INTO TAB (colTimestamp)
VALUES ('2020-05-07 10:05:05.301011')
例2:
INSERT INTO TAB (colTimestamp)
VALUES ('2020-05-07T10:05:05.301011')
语法是 - YYYY-MM-DD hh:mi:ss.SS
LocalDateTime 的格式,至少由 Java DateFormatter 所采用,将是:
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd hh:mm:ss.SS");
LocalDateTime localDateTime = LocalDateTime.of(2021, 12, 31, 14, 30, 15, 300);
System.out.println(formatter.format(localDateTime));
这会给:
2022-12-31 02:30:15.00
下表描述了 ANSI SQL 类型与java.time
类型的映射:
ANSI SQL | Java SE 8 |
---|---|
日期 | 本地日期 |
时间 | 当地时间 |
时间戳 | 本地日期时间 |
时区时间 | 偏移时间 |
带时区的时间戳 | 偏移日期时间 |
假设您的数据库列的类型为TIMESTAMP
,您可以将给定的日期时间字符串解析为LocalDateTime
,如下所示:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-05-07-10.05.05.301011";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral("-")
.appendPattern("HH.mm.ss")
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.toFormatter(Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
System.out.println(ldt);
}
}
输出:
2020-05-07T10:05:05.301011
现在,您可以将此LocalDateTime
存储到数据库中,如下所示:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, ldt);
st.executeUpdate();
st.close();
下面给出了从 columnfoo 检索 LocalDate 的示例代码:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
LocalDateTime ldt = rs.getObject(1, LocalDateTime.class));
System.out.println(ldt);
}
rs.close();
st.close();
从Trail: Date Time 中了解有关现代日期时间 API * 的更多信息。
* 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 通过 desugaring 可用的 Java 8+ API 。 请注意,Android 8.0 Oreo 已提供对java.time
支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.