2

我尝试从 oracle db 获取一些数据,将这些数据放入 json 并在其他地方使用它,但是我在转换 timestamptz 时遇到问题。Oracle 以字符串格式为我提供带有时区的时间戳,例如“23.10.14 18:34:16,000000 ASIA/NOVOSIBIRSK”。这是我的一些代码。

public void loadFromDb(ResultSet resultSet, Connection oc) throws SQLException {
    ResultSetMetaData metaData = resultSet.getMetaData();
    int columnCount = metaData.getColumnCount();
    for (int i = 1; i <= columnCount; i++) {
        Object obj = resultSet.getObject(i);
        if (obj == null)
            continue;
        if (obj instanceof TIMESTAMPTZ) {
            TIMESTAMPTZ ts = (TIMESTAMPTZ) obj;
            if (oc != null) {
                super.setValue(metaData.getColumnName(i), ts.stringValue(oc));
            } else {
                super.setValue(metaData.getColumnName(i), ts.stringValue());
            }
    }
}

我得到了这个例外

java.sql.SQLException: Conversion to String failed
at oracle.sql.Datum.stringValue(Datum.java:181)

顺便说一句,早些时候我得到了像'XX:XX'这样的数字格式的时区,这段代码也不起作用,但super.setValue(metaData.getColumnName(i), ts.stringValue(null))现在以这种方式工作这个魔法thtows nullpointerexception。请帮助我,因为我尝试了 javadocs 中的所有内容。

4

2 回答 2

0

TIMESTAMP不是字符串,反之亦然。您需要使用TO_CHAR所需的格式将其转换为字符串。

SQL> SELECT SYSTIMESTAMP
  2  FROM   dual
  3  /

SYSTIMESTAMP
---------------------------------------------------------------------------
24-OCT-14 11.14.55.116000 AM +05:30

SQL>
SQL> SELECT TO_CHAR(systimestamp, 'DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') tm
  2  FROM dual
  3  /

TM
-------------------------------------
24-OCT-2014 11:14:55.163000 +05:30

SQL> SELECT to_timestamp_tz('24-OCT-2014 11:07:40.348000 +05:30','DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') tm
  2  FROM dual
  3  /

TM
---------------------------------------------------------------------------
24-OCT-14 11.07.40.348000000 AM +05:30

SQL> SELECT TO_TIMESTAMP('24-OCT-2014', 'DD-MON-YYYY')
  2  FROM dual
  3  /

TO_TIMESTAMP('24-OCT-2014','DD-MON-YYYY')
---------------------------------------------------------------------------
24-OCT-14 12.00.00.000000000 AM

让我们验证一下。

SQL> set serveroutput on;
SQL> DECLARE
  2    tm_stamp  TIMESTAMP;
  3    tm_string VARCHAR2(30);
  4  BEGIN
  5    SELECT SYSTIMESTAMP INTO tm_stamp FROM dual;
  6    dbms_output.put_line(tm_stamp);
  7    SELECT SYSTIMESTAMP INTO tm_string FROM dual;
  8    dbms_output.put_line(tm_string);
  9  END;
 10  /
24-OCT-14 11.17.35.180000 AM
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 7


SQL>

因此,tm_string 不能存储时间戳,因为 tm_stamp 是字符串类型而不是时间戳。

正确的方法是将其显式转换为字符串。

SQL> DECLARE
  2    tm_stamp  TIMESTAMP;
  3    tm_string VARCHAR2(50);
  4  BEGIN
  5    SELECT TO_CHAR(systimestamp, 'DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') INTO tm_string FROM dual;
  6    dbms_output.put_line(tm_string);
  7  END;
  8  /
24-OCT-2014 11:25:20.060000 +05:30

PL/SQL procedure successfully completed.

SQL>
于 2014-10-24T05:55:56.203 回答
0

的格式TIMESTAMPTZ据可查。我们目前使用以下代码

如果您使用的是 Java SE 8 和 ojdbc8,则可以使用getObject(int, OffsetDateTime.class). 如果您使用getObject(int, ZonedDateTime.class),您可能会受到错误 25792016的影响。

于 2017-04-24T06:04:08.993 回答