12

私は周りを検索しましたが、驚くべきことに、OracleJDBCのこれに対する答えを見つけることができません。この密接に関連する質問には、PostgreSQLとMySQLに対する回答があります。

基本的に、2つの異なるタイムゾーンに2つのアプリケーションサーバーが1つのOracleデータベースにタイムスタンプを書き込んでいる場合、どうなりますか?ありがとう。

編集:クエリを実行するときにJDBCがデータベースに送信する値は、ローカルタイムゾーンにあるように見えることを追加する必要があります。

4

1 に答える 1

9

何が起こるかを正確に把握するために、いくつかのテスト JDBC コードをまとめました。結果は興味深いものでした。TIMESTAMPOracle には、TIMESTAMP WITH TIME ZONE、 、およびの3 つの密接に関連したデータ型がありTIMESTAMP WITH LOCAL TIME ZONEます。まったく同じコードを使用して、2 つの異なるボックスから実行しました。1 つは "America/New_York" タイムゾーンで、もう 1 つは UTC で実行されています。どちらも同じデータベースにヒットし、UTC で実行されます。Oracle 11.2.0.2.0 ドライバーを使用していました。

  • 列は、TIMESTAMPJava コードを実行しているマシンの現地時間に設定されていました。タイムゾーンの変換は実行されませんでした。
  • 列は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
            }
        }
    }
}
于 2012-08-27T21:26:34.110 に答える