iBA를 사용한 Oracle SQL DATE 변환 문제Java JDBC를 통한 TIS
현재 iBA를 사용하는 Oracle SQL DATE 변환 문제로 씨름하고 있습니다.Java의 TIS입니다.
Oracle JDBC Thin driver ojdbc14 버전 10.2.0.4.0.iBATIS 버전 2.3.2. Java 1.6.0_10-rc2-b32를 사용하고 있습니다.
이 문제는 다음 SQL에서 반환되는 DATE 유형 열을 중심으로 발생합니다.
SELECT *
FROM TABLE(pk_invoice_qry.get_contract_rate(?,?,?,?,?,?,?,?,?,?)) order by from_date
패키지 프로시저 호출은 테이블에 대한 선택 쿼리인 것처럼 결과 세트를 읽기 쉬운 TABLE에 포장된 참조자를 반환합니다.
PL/SQL Developer에서 반환된 열 중 하나인 FROM_DATE는 SQL DATE 유형으로 다음 시간대로 정밀도가 지정됩니다.
Tue Dec 16 23:59:00 PST 2008
하지만 iBA를 통해 액세스할 때TIS 및 JDBC 값은 오늘날 정밀도만 유지합니다.
Tue Dec 16 12:00:00 AM PST 2008
이는 다음과 같이 표시될 때 더 명확합니다.
했어야 하는 일:
1229500740000 milliseconds since epoch
Tuesday, December 16, 2008 11:59:00 PM PST
하지만 대신 이것을 얻는 것은:
1229414400000 milliseconds since epoch
Tuesday, December 16, 2008 12:00:00 AM PST
(as instance of class java.sql.Date)
아무리 노력해도 Java JDBC 및 iBATIS를 통해 반환되는 이 DATE 열의 전체 정밀도를 노출할 수 없습니다.
what iBATIS가 매핑되는 위치:
FROM_DATE : 2008-12-03 : class java.sql.Date
현재 iBATIS 매핑은 다음과 같습니다.
<result property="from_date" jdbcType="DATE" javaType="java.sql.Date"/>
저도 해봤어요.
<result property="from_date" jdbcType="DATETIME" javaType="java.sql.Date"/>
또는
<result property="from_date" jdbcType="TIMESTAMP" javaType="java.sql.Timestamp"/>
그러나 시도된 모든 매핑은 동일한 잘린 날짜 값을 생성합니다.마치 JDBC가 iBA 이전에 데이터 정밀도가 떨어지는 피해를 이미 입힌 것과 같습니다.TIS는 그것을 만지기도 합니다.
JDBC와 iBA를 통해 데이터 정확도를 어느 정도 떨어뜨리고 있는 것이 분명합니다.테스트 스크립트와 동일한 SQL 스니펫을 실행하는 PL/SQL Developer에 있을 때는 TIS가 발생하지 않습니다.전혀 용납할 수 없고, 매우 실망스럽고, 궁극적으로 매우 무섭습니다.
전체 정보(여기에 설명된 것보다 더 복잡하고 사용 중인 Oracle 드라이버의 특정 버전에 따라 달라질 수 있음)는 Richard Yee의 답변에 있습니다. [이제 Nabble 링크 만료]
네이블에서 만료되기 전에 빠르게 붙잡기...
Roger, 참조: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_01
구체적으로: 단순 데이터 유형 DATE 및 TIMESTAMP는 어떻게 됩니까? 이 섹션은 단순 데이터 유형에 대해 설명합니다. :-)
9.2 이전 버전의 Oracle JDBC 드라이버는 DATE SQL 유형을 java.sql에 매핑했습니다.타임스탬프.Oracle DATE SQL 유형에는 java.sql과 마찬가지로 날짜 및 시간 정보가 모두 포함되어 있기 때문에 어느 정도 의미가 있습니다.타임스탬프.java.sql에 대한 더 명확한 매핑.날짜가 java.sql로 다소 문제가 있었습니다.날짜에 시간 정보가 포함되어 있지 않습니다.또한 RDBMS가 TIMESTAMP SQL 유형을 지원하지 않아 DATE를 TIMESTAMP에 매핑하는 데 문제가 없었습니다.
9.2에서 TIMESTAMP 지원이 RDBMS에 추가되었습니다. DATE와 TIMESTAMP의 차이점은 TIMESTAMP는 나노초를 포함하고 DATE는 나노초를 포함하지 않는다는 것입니다.따라서 9.2부터는 DATE가 DATE에 매핑되고 TIMESTAMP가 TIMESTAMP에 매핑됩니다.유감스럽게도 시간 정보를 포함하기 위해 날짜 값에 의존했다면 문제가 있습니다.
이 문제를 해결하는 몇 가지 방법이 있습니다.
날짜 대신 타임스탬프를 사용하도록 테이블을 변경합니다.이것은 아마도 거의 가능하지 않을 것이지만, 가능할 때 가장 좋은 해결책입니다.
defineColumnType을 사용하여 열을 DATE가 아닌 TIME으로 정의하도록 응용 프로그램을 변경합니다.꼭 사용해야 하는 경우가 아니면 defineColumnType을 사용하고 싶지 않기 때문에 문제가 있습니다('ColumnType 정의란 무엇이며 언제 사용해야 합니까?' 참조).
getObject 대신 getTimestamp를 사용하도록 응용 프로그램을 변경합니다.이것은 가능한 경우 좋은 해결책이지만 많은 응용 프로그램에 getObject에 의존하는 일반 코드가 포함되어 있기 때문에 항상 가능한 것은 아닙니다.
V8 호환 연결 속성을 설정합니다.이 메시지는 JDBC 드라이버에게 새 매핑이 아닌 기존 매핑을 사용하도록 지시합니다.이 플래그는 연결 속성 또는 시스템 속성으로 설정할 수 있습니다.java.util에 연결 속성을 추가하여 설정합니다.속성 개체가 DriverManager.getConnection 또는 OracleDataSource에 전달되었습니다.연결 속성을 설정합니다.Java 명령줄에 -D 옵션을 포함하여 시스템 속성을 설정합니다.
java -Doracle.jdbc.V8Compatible="true" MyApp Oracle JDBC 11.1은 이 문제를 해결합니다.이 릴리스부터 드라이버는 SQL DATE 열을 java.sql에 매핑합니다.기본적으로 타임스탬프입니다.올바른 매핑을 얻기 위해 V8Compatible을 설정할 필요가 없습니다.V8 Compatible은 강력하게 사용되지 않습니다.당신은 그것을 전혀 사용해서는 안 됩니다.만약 당신이 그것을 진실로 설정한다면, 그것은 아무 것도 해치지 않을 것이지만, 당신은 그것을 사용하는 것을 중단해야 합니다.
이러한 방식으로 거의 사용되지 않았지만 V8 Compatible은 DATE를 DATE에서 DATE에서 DATE 문제를 해결하기 위한 것이 아니라 8i 데이터베이스와의 호환성을 지원하기 위해 존재했습니다.8i 이상의 데이터베이스는 TIMESTAMP 유형을 지원하지 않습니다.V8Compatible을 설정하면 데이터베이스에서 읽을 때 SQL DATE가 Timestamp에 매핑될 뿐만 아니라 데이터베이스에 쓸 때 모든 Timestamp가 SQL DATE로 변환됩니다.8i는 지원되지 않으므로 11.1 JDBC 드라이버는 이 호환성 모드를 지원하지 않습니다.이러한 이유로 V8Compatible은 지원되지 않습니다.
위에서 설명한 대로 11.1 드라이버는 데이터베이스에서 읽을 때 기본적으로 SQL DATE를 타임스탬프로 변환합니다.이것은 항상 옳은 일이었고 9i의 변화는 실수였습니다.11.1 드라이버가 올바른 동작으로 되돌아갔습니다.응용 프로그램에서 V8 호환을 설정하지 않았더라도 대부분의 경우 동작에 차이가 없어야 합니다.getObject를 사용하여 DATE 열을 읽을 경우 차이가 있을 수 있습니다.결과는 날짜가 아닌 타임스탬프가 됩니다.타임스탬프는 날짜의 하위 클래스이므로 일반적으로 문제가 되지 않습니다.시간 구성 요소를 자르기 위해 DATE에서 DATE로의 변환에 의존했거나 값에 대해 String을 수행한 경우에 차이가 있을 수 있습니다.그렇지 않으면 변경 사항이 투명해야 합니다.
어떤 이유에서인지 앱이 이러한 변경에 매우 민감하고 9i-10g 동작만 수행해야 하는 경우에는 연결 속성을 설정할 수 있습니다.mapDateToTimestamp를 false로 설정하면 드라이버가 기본 9i-10g 동작으로 되돌아가고 DATE를 Date로 매핑합니다.
가능하면 열 유형을 DATE가 아닌 TIMESTAMP로 변경해야 합니다.
-리처드
로저 보스는 다음과 같이 썼습니다.스택 오버플로에 대해 다음과 같은 질문/문제를 게시했으므로 해결 방법을 아는 사람이 있다면 거기서 답변하는 것을 보면 좋을 것입니다.
iBA를 사용한 Oracle SQL DATE 변환 문제Java JDBC를 통한 TIS
문제 설명은 다음과 같습니다.
현재 iBA를 사용하는 Oracle sql DATE 변환 문제로 씨름하고 있습니다.Java의 TIS입니다.
Oracle JDBC Thin driver ojdbc14 버전 10.2.0.4.0.iBATIS 버전 2.3.2. Java 1.6.0_10-rc2-b32를 사용하고 있습니다.
이 문제는 다음 SQL에서 반환되는 DATE 유형 열을 중심으로 발생합니다.
선택 * FROM TABLE(pk_invoice_qry.get_contract_rate(?,?,?,?)를 from_date로 주문합니다.
패키지 프로시저 호출은 테이블에 대한 선택 쿼리인 것처럼 결과 세트를 읽기 쉬운 TABLE에 포장된 참조자를 반환합니다.
PL/SQL Developer에서 반환된 열 중 하나인 FROM_DATE는 SQL DATE 유형으로 다음 시간대로 정밀도가 지정됩니다.
Tue Dec 16 23:59:00 PST 2008
하지만 iBA를 통해 액세스할 때TIS 및 JDBC 값은 오늘날 정밀도만 유지합니다.
Tue Dec 16 12:00:00 AM PST 2008
이는 다음과 같이 표시될 때 더 명확합니다.
2008년 12월 16일 화요일 11:59:00 PM PST 이후 1229500740000 밀리초여야 합니다.
그러나 대신 이것을 얻는 것: 2008년 12월 16일 화요일 12:00:00 AM PST 이후 1229414400000 밀리초 (클래스 java.sql의 인스턴스로).날짜)
아무리 노력해도 Java JDBC 및 iBATIS를 통해 반환되는 이 DATE 열의 전체 정밀도를 노출할 수 없습니다.
what iBATIS가 매핑되는 위치:
FROM_DATE : 2008-12-03 : class java.sql.날짜.
현재 iBATIS 매핑은 다음과 같습니다.
저도 해봤어요.
또는
그러나 시도된 모든 매핑은 동일한 잘린 날짜 값을 생성합니다.마치 JDBC가 iBA 이전에 데이터 정밀도 손실의 손상을 이미 수행한 것과 같습니다.TIS는 그것을 만지기도 합니다.
JDBC와 iBA를 통해 데이터 정확도를 일부 떨어뜨리고 있는 것이 분명합니다.테스트 스크립트와 동일한 SQL 스니펫을 실행하는 PL/SQL Developer에 있을 때는 TIS가 발생하지 않습니다.전혀 용납할 수 없고, 매우 실망스럽고, 궁극적으로 매우 무섭습니다.
저는 이 문제를 해결하는 방법을 찾았습니다. iBATIS는 사용자 지정 유형 핸들러를 등록할 수 있도록 허용합니다.sqlmap-config.xml 파일에 다음과 같이 추가했습니다.
<typeAlias alias="OracleDateHandler" type="com.tideworks.ms.CustomDateHandler"/>
<typeHandler callback="OracleDateHandler" jdbcType="DATETIME" javaType="date"/>
그런 다음 iBATIS TypeHandler Callback 인터페이스를 구현하는 클래스를 추가했습니다.
// corrected getResult()/setParameter() to correctly deal with when value is null
public class CustomDateHandler implements TypeHandlerCallback {
@Override
public Object getResult(ResultGetter getter) throws SQLException {
final Object obj = getter.getTimestamp();
return obj != null ? (Date) obj : null;
}
@Override
public void setParameter(ParameterSetter setter,Object value) throws SQLException {
setter.setTimestamp(value != null ? new Timestamp(((Date)value).getTime()) : null);
}
@Override
public Object valueOf(String datetime) {
return Timestamp.valueOf(datetime);
}
}
Oracle DATE를 매핑할 필요가 없을 때 다음과 같이 설명합니다.
<result property="from_date" jdbcType="DATETIME" javaType="date"/>
는 사하여문해다니습결했를제용▁using를 사용하여 문제를 했습니다.jdbcType="TIMESTAMP"
에 jdbcType="DATE"
문제:
<result column="MY_UTC_POS" property="myUtcPosition" jdbcType="DATE" />
해결됨:
<result column="MY_UTC_POS" property="myUtcPosition" jdbcType="TIMESTAMP" />
문제는 Oracle 드라이버에 있습니다.
제가 찾은 가장 좋은 해결책은 모든 jdbcType="DATE"를 jdbcType="로 변경하는 것이었습니다.TIMESTAMP" 및 모든 #columen_name:DATE # ~ #columnn_name:타임스탬프 #
변경 사항:
<result property="from_date" jdbcType="DATE" javaType="java.sql.Date"/>
로.
<result property="from_date" jdbcType="TIMESTAMP" javaType="java.sql.Date"/>
는 문는의사다니입용의 입니다.java.sql.Date
자바독에 따르면 밀리초 값은 다음과 같이 요약됩니다.java.sql.Date
된 특정 및하여 ' 합니다. SQL SQL의 합니다. 즉, 인스턴스는 0으로 설정됩니다.DATE
.
예, 알겠습니다. 일반 SQL DATE 표준은 오늘의 해상도만 저장해야 합니다.다음은 Oracle의 DATE 유형에 대한 토막글입니다.
Oracle은 SQL2 표준과 다르지만 날짜와 시간을 모두 지원합니다.Oracle은 두 개의 독립된 엔티티(날짜와 시간)를 사용하는 대신 DATE 하나만 사용합니다.DATE 유형은 월, 일 및 연도뿐만 아니라 시, 분 및 초도 포함하는 특수 내부 형식으로 저장됩니다.
따라서 Oracle의 DATE가 표준 SQL DATE를 초과합니다.
흠, Oracle PL/SQL 사용자들은 DATE를 광범위하게 사용하여 해상도에 의존하는 값을 초 단위로 유지합니다.iB처럼 보입니다.ATIS에는 java.sql을 통해 DATE를 해석하는 대신 Hibernate sql 방언 개념과 같은 것이 필요합니다.Date는 java.util을 통해 재정의하고 대신 해석할 수 있습니다.날짜. Javadocs에서 밀리초 단위의 해상도를 허용하는 것으로 정의합니다.
불행히도 매핑을 다음과 같은 것으로 변경했을 때:
<result property="from_date" jdbcType="DATE" javaType="java.util.Date"/>
또는
<result property="from_date" jdbcType="DATETIME" javaType="java.util.Date"/>
여전히 겉보기에는 SQL DATE를 java.sql로 처음 번역한 것 같습니다.날짜 및 시간 정확도가 손실되었습니다.
Richard Yee는 Oracle의 최신 드라이버가 문제를 해결한다고 말합니다.저는 그것을 확인할 수 있습니다.오늘 ojdbc5.jar(11.2.0.1.0)로 업그레이드된 10.2 드라이버에서도 동일한 문제가 발생했지만 이제 문제가 사라졌습니다.
언급URL : https://stackoverflow.com/questions/383783/oracle-sql-date-conversion-problem-using-ibatis-via-java-jdbc
'programing' 카테고리의 다른 글
SQLite 대 SQL Server (0) | 2023.07.20 |
---|---|
Oracle이 null 문자열과 빈 문자열을 구분하지 않습니까? (0) | 2023.07.20 |
ipython 내부에서 python 스크립트 실행 중 (0) | 2023.07.20 |
꺼내기 요청에서 GitHub 클론? (0) | 2023.07.20 |
sys.path /PYthonPATH에 디렉토리 추가 (0) | 2023.07.20 |