Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

използвайки типа данни datetimeoffset с jTDS

Както е споменато в раздела „Обратна съвместимост за клиенти от по-ниско ниво“ на datetimeoffset документация , можем да работим с низови представяния на datetimeoffset стойности. Всъщност, ако извлечем datetimeoffset стойност с jTDS 1.3.1 получаваме java.lang.String стойност на формуляра

YYYY-MM-DD hh:mm:ss[.nnnnnnn] {+|-}hh:mm

Такава стойност може да бъде анализирана така:

// rs is our ResultSet object
String valueRetrieved = rs.getString(1);  // e.g., "2016-12-08 12:34:56.7850000 -07:00"
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS ZZZZZ");
ZonedDateTime zdt = ZonedDateTime.parse(valueRetrieved, dtf);

Що се отнася до писането на datetimeoffset стойност за SQL Server, jTDS не може да обработи правилно актуализация чрез .setTimestamp , например на моята машина ...

java.sql.Timestamp ts = java.sql.Timestamp.valueOf("2016-12-08 12:34:56.785");  // local
String tsString = formatTimestampForDateTimeOffset(ts);  // (see below)
System.out.printf("             java.sql.TimeStamp value: %s (%d ms since epoch)%n", tsString, ts.getTime());

System.out.println();
System.out.println("Saving via setTimestamp ...");
String sqlUpdate = "UPDATE dtoTable SET dtoCol = ? WHERE id=1";
try (PreparedStatement s = conn.prepareStatement(sqlUpdate)) {
    s.setTimestamp(1, ts);  // pass the Timestamp itself
    s.executeUpdate();
}
String valueRetrieved;
try (
        Statement s = conn.createStatement();
        ResultSet rs = s.executeQuery("SELECT dtoCol FROM dtoTable WHERE id=1")) {
    rs.next();
    valueRetrieved = rs.getString(1);
    System.out.printf("    jTDS saved the TimeStamp value as: %s%n", valueRetrieved);
}

... произвежда ...

         java.sql.TimeStamp value: 2016-12-08 12:34:56.785 -07:00 (1481225696785 ms since epoch)

Saving via setTimestamp ...
jTDS saved the TimeStamp value as: 2016-12-08 12:34:56.7870000 +00:00

... което не само неправилно задава отместването на часовата зона на +00:00 (без да променя самата стойност за дата/час), но и добавя няколко милисекунди просто за забавление.

Ако обаче преобразуваме стойността на Timestamp в правилно форматиран низ, например, ...

public static String formatTimestampForDateTimeOffset(java.sql.Timestamp ts) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ZZZZZ");
    String s = sdf.format(new Date(ts.getTime()));
    // T-SQL *requires* the colon in the timezone offset: -07:00, not -0700
    int colonPosition = s.length() - 2;
    return s.substring(0, colonPosition) + ":" + s.substring(colonPosition);
}

... и използвайте .setString вместо .setTimestamp , след това datetimeoffset стойността е запазена правилно:

Saving via setString ...
jTDS saved the formatted String as: 2016-12-08 12:34:56.7850000 -07:00
           parsed to ZonedDateTime: 2016-12-08T12:34:56.785-07:00
              converted to Instant: 2016-12-08T19:34:56.785Z
       converted to java.util.Date: Thu Dec 08 12:34:56 MST 2016



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проблем с разрешенията в SSMS:Разрешението SELECT беше отказано за обекта 'extended_properties', базата данни 'mssqlsystem_resource', ... Грешка 229)

  2. Обосновка за редовно обслужване на SQL сървър

  3. Какво е SQL Server?

  4. Не може да се свърже pyODBC с SQL Server 2008 Express R2

  5. Настройка на сесията за поддръжка на индексирани изгледи