2014-10-24 5 views
2

오라클 db에서 데이터를 가져 와서이 데이터를 json에 넣고 다른 위치에서 사용하려고합니다.하지만 timestamptz를 변환하는 데 문제가 있습니다. 오라클은 "23.10.14 18 : 34 : 16,000000 ASIA/NOVOSIBIRSK"와 같은 문자열 형식의 타임 존을 가진 타임 스탬프를 제공합니다. 여기 내 코드의 일부.oracle.sql.TIMESTAMPTZ를 문자열 값으로 변환하는 데 문제가 있습니다.

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()); 
      } 
    } 
} 

와 나는이 예외를 얻을

BTW
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에있는 모든 것을 시도했기 때문에 제발 도와주세요.

+0

jdbc 드라이버에 문제가있을 수 있으며 이것을 읽었습니까? http://stackoverflow.com/questions/17559658/oracle-jdbc-retrieving-timestamp-with-time-zone-value-in-iso-8601-format – Multisync

+0

문제를 해결하는 가장 쉬운 방법은 문자열을 검색하는 것입니다 시간대가있는 타임 스탬프 표현 (해당되는 경우) – Multisync

+0

@Multisync 어쩌면 내가 잘못 알고 있지만이 문제는 - 시간대가있는 타임 스탬프 문자열 표현을 얻습니다. – mechanikos

답변

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_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> 
+0

을 돌려 주지만, 자바의 리소스는 제한되어 있습니다. 난 그냥 결과를 반환 프로 시저를 호출합니다. – mechanikos

0

TIMESTAMPTZ의 형식은 well documented입니다. 현재 the following code을 사용하고 있습니다.

Java SE 8 및 ojdbc8을 사용하는 경우 getObject(int, OffsetDateTime.class)을 사용할 수 있습니다. getObject(int, ZonedDateTime.class)을 사용하는 경우 bug 25792016의 영향을받을 수 있습니다.

관련 문제