Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Was passiert im Oracle JDBC-Treiber mit der Zeitzone, wenn Sie ein Java-Datum in eine TIMESTAMP-Spalte schreiben?

Ich habe Test-JDBC-Code zusammengestellt, um genau herauszufinden, was passiert. Die Ergebnisse waren interessant. Oracle hat drei eng verwandte Datentypen:TIMESTAMP , TIMESTAMP WITH TIME ZONE , und TIMESTAMP WITH LOCAL TIME ZONE . Ich habe genau denselben Code genommen und ihn von zwei verschiedenen Boxen ausgeführt, einer in der Zeitzone "America/New_York" und einer, der auf UTC läuft. Beide trafen auf dieselbe Datenbank, die in UTC ausgeführt wurde. Ich habe den Oracle 11.2.0.2.0-Treiber verwendet.

  • Der TIMESTAMP -Spalte wurde auf die Ortszeit des Computers gesetzt, der den Java-Code ausführt. Es wurde keine Zeitzonenumrechnung durchgeführt.
  • Der TIMESTAMP WITH TIME ZONE Spalte hat die Zeit in die Zeitzone übersetzt, in der sich der JDBC-Client befand.
  • Der TIMESTAMP WITH LOCAL TIME ZONE -Spalte übersetzte auch die Zeit in die Zeitzone, in der sich der JDBC-Client befand.

Dieser Artikel , das etwas älter ist, gibt an, dass TIMESTAMP WITH TIME ZONE ist ziemlich nutzlos, wenn Sie etwas wie Indizes oder Partitionen machen wollen. Es scheint jedoch TIMESTAMP WITH LOCAL TIME ZONE zu sein könnte sehr nützlich sein. (Nicht sicher, was passiert, wenn Sie die Zeitzone des Servers ändern, aber es scheint intelligent mit den lokalen Zeitzonen von JDBC-Clients umzugehen). Ich hatte noch keine Gelegenheit, das Indizierungsverhalten usw. mit diesen Datentypen zu testen.

Fügen Sie unten meine Beispielklasse ein, wenn Sie meine Tests in Ihrer Umgebung reproduzieren möchten.

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
            }
        }
    }
}