sql >> Database teknologi >  >> RDS >> Oracle

Hvad sker der i Oracle JDBC-driveren med tidszonen, når du skriver en Java-dato til en TIMESTAMP-kolonne?

Jeg sammensatte en test JDBC-kode for at finde ud af præcis, hvad der sker. Resultaterne var interessante. Oracle har tre tæt relaterede datatyper:TIMESTAMP , TIMESTAMP WITH TIME ZONE , og TIMESTAMP MED LOKAL TIDZONE . Jeg tog nøjagtig den samme kode og kørte den fra to forskellige bokse, en i "America/New_York"-tidszonen og en, der kører på UTC. Begge rammer den samme database, kører i UTC. Jeg brugte Oracle 11.2.0.2.0-driveren.

  • TIMESTAMP kolonne blev indstillet til, hvad den lokale tid var på den maskine, der udførte Java-koden. Der blev ikke udført nogen tidszoneoversættelse.
  • TIDSSTAMPE MED TIDSZONE kolonne oversatte tiden til den tidszone, JDBC-klienten var i.
  • TIMESTAMP MED LOKAL TIDZONE kolonne oversatte også tiden til den tidszone, JDBC-klienten var i.

Denne artikel , som er lidt ældre, angiver, at TIMESTAMP WITH TIME ZONE er stort set ubrugelig, hvis du vil gøre noget som indekser eller partitioner. Det ser dog ud til at TIMESTAMP WITH LOCAL TIME ZONE kan være yderst nyttig. (Ikke sikker på, hvad der sker, hvis du ændrer serverens tidszone, men det ser ud til at være intelligent omkring JDBC-klienters lokale tidszoner). Jeg har ikke haft mulighed for at teste indekseringsadfærd osv. med disse datatyper.

Indsæt min prøveklasse nedenfor, hvis du gerne vil gengive mine tests i dit miljø.

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



  1. MySql Workbench-installationsprogrammet kræver Visual C++ 2015 Redistributable Package for at blive installeret, men det er allerede installeret

  2. Skift kommando i Aurora DB (tilføj en ny kolonne)

  3. Sådan får du information om kompileringsfejl i Oracle/TOAD

  4. Sådan forvandler du et json-array til rækker i postgres