我四处搜寻,令人惊奇找不到甲骨文JDBC的答案。 此密切相关的问题,对PostgreSQL和MySQL的答案。
基本上,如果我有两个不同的时区写入时间戳一个Oracle数据库的两个应用程序服务器,会发生什么? 谢谢。
编辑:我要补充,这似乎像JDBC被发送到数据库时,我做的查询是在我的本地时区的价值。
我四处搜寻,令人惊奇找不到甲骨文JDBC的答案。 此密切相关的问题,对PostgreSQL和MySQL的答案。
基本上,如果我有两个不同的时区写入时间戳一个Oracle数据库的两个应用程序服务器,会发生什么? 谢谢。
编辑:我要补充,这似乎像JDBC被发送到数据库时,我做的查询是在我的本地时区的价值。
我把一些测试JDBC代码,以弄清楚到底发生了什么。 结果很有趣。 Oracle有三个密切相关的数据类型: TIMESTAMP
, TIMESTAMP WITH TIME ZONE
和TIMESTAMP WITH LOCAL TIME ZONE
。 我采取了完全相同的代码,并从两个不同的盒子,一个在“美国/纽约”时区,并在UTC一个人跑来跑去了。 双双创下同一个数据库中,UTC运行。 我使用Oracle 11.2.0.2.0驱动程序。
TIMESTAMP
列设置为任何本地时间执行Java代码的机器上。 未进行时区转换。 TIMESTAMP WITH TIME ZONE
列转换到任何时区的JDBC客户端是时间。 TIMESTAMP WITH LOCAL TIME ZONE
列也翻译成任何时区的JDBC客户端是时间。 这篇文章 ,这是一个年纪大一点,表明TIMESTAMP WITH TIME ZONE
几乎是无用的,如果你想要做像索引或分区的任何东西。 然而,这似乎是TIMESTAMP WITH LOCAL TIME ZONE
可能是非常有用的。 (不知道如果你改变了服务器的时区,但它似乎是聪明的有关JDBC客户端的本地时区会发生什么)。 我还没有机会测试索引行为等这些数据类型。
粘贴在下面,如果你想重现我的测试环境中的我的示例类。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Date;
// create table x_tst_ts_tab(
// os_name varchar(256)
// ts timestamp,
// ts_with_tz timestamp with time zone,
// ts_with_local_tz timestamp with local time zone
// )
class TSTest {
public static final void main(String[] argv) throws Exception {
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection(
"your_connection_string",
"your_user_name",
"your_password");
try {
// Insert some data
Date nowDate = new Date();
Timestamp nowTimestamp = new Timestamp(nowDate.getTime());
PreparedStatement insertStmt = conn.prepareStatement(
"INSERT INTO x_tst_ts_tab"
+ " (os_name, ts, ts_with_tz, ts_with_local_tz)"
+ " VALUES (?, ?, ?, ?)");
try {
insertStmt.setString(1, System.getProperty("os.name"));
insertStmt.setTimestamp(2, nowTimestamp);
insertStmt.setTimestamp(3, nowTimestamp);
insertStmt.setTimestamp(4, nowTimestamp);
insertStmt.executeUpdate();
} finally {
try {
insertStmt.close();
} catch (Throwable t) {
// do nothing
}
}
System.out.println("os_name, ts, ts_with_tz, ts_with_local_tz");
// Read back everything in the DB
PreparedStatement selectStmt = conn.prepareStatement(
"SELECT os_name, ts, ts_with_tz, ts_with_local_tz"
+ " FROM dom_fraud_beacon.x_tst_ts_tab");
ResultSet result = null;
try {
result = selectStmt.executeQuery();
while (result.next()) {
System.out.println(
String.format("%s,%s,%s,%s",
result.getString(1),
result.getTimestamp(2).toString(),
result.getTimestamp(3).toString(),
result.getTimestamp(4).toString()
));
}
} finally {
try {
result.close();
} catch (Throwable t) {
// do nothing
} finally {
try {
selectStmt.close();
} catch (Throwable t) {
// do nothing
}
}
}
} finally {
try {
conn.close();
} catch (Throwable t) {
// do nothing
}
}
}
}