Oracle проблема преобразования ДАТЫ SQL с помощью iBATIS через Java JDBC

Для всех ваших представлений вместо match_parent

используйте 0dp в xml или выберите match_constraint в представлении разработки

13
задан Jason Plank 16 March 2011 в 00:05
поделиться

7 ответов

Полная информация (и это более сложно, чем описанный здесь и могло бы зависеть, на которую конкретную версию драйверов Oracle используются), находится в ответе Richard Yee здесь - [теперь истек ссылка на Nabble]


Быстрый захват, прежде чем это истечет от nabble...

Roger, см.: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_01

Конкретно: Простые типы данных, Что продолжает ДАТУ и МЕТКУ ВРЕМЕНИ? Этот раздел находится на простых типах данных.:-)

До 9,2, драйверы JDBC Oracle отобразили ДАТУ тип SQL на java.sql. Метка времени. Это сделало определенное количество смысла, потому что ДАТА Oracle, тип SQL содержит обе информации о дате и времени, как делает java.sql. Метка времени. Более очевидное отображение на java.sql. Дата была несколько проблематична как java.sql. Дата не включает информацию времени. Также имело место, что RDBMS не поддерживал МЕТКУ ВРЕМЕНИ тип SQL, таким образом, не было никакой проблемы с отображающейся ДАТОЙ для Добавления метки времени.

В 9,2 МЕТКАХ ВРЕМЕНИ поддержка была добавлена к RDBMS. Различие между ДАТОЙ и МЕТКОЙ ВРЕМЕНИ - то, что МЕТКА ВРЕМЕНИ включает наносекунды, и ДАТА не делает. Так, начинаясь в 9,2, ДАТА отображается до настоящего времени, и МЕТКА ВРЕМЕНИ отображается на Метке времени. К сожалению, при доверии значениям ДАТЫ для содержания информации времени, существует проблема.

Существует несколько способов решить эту проблему:

Измените свои таблицы для использования МЕТКИ ВРЕМЕНИ вместо ДАТЫ. Это, вероятно, редко возможно, но это - лучшее решение, когда это.

Измените свое приложение для использования defineColumnType для определения столбцов как МЕТКУ ВРЕМЕНИ, а не ДАТУ. Существуют проблемы с этим, потому что Вы действительно не хотите использовать defineColumnType, если Вы не имеете к (см. то, Что defineColumnType и когда я должен использовать его?).

Измените Вас приложение для использования getTimestamp, а не getObject. Это - хорошее решение, если это возможно, однако много приложений содержат общий код, который полагается на getObject, таким образом, это не всегда возможно.

Установите свойство соединения V8Compatible. Это говорит драйверам JDBC использовать старое отображение, а не новое. Можно установить этот флаг или как свойство соединения или как системное свойство. Вы устанавливаете свойство соединения путем добавления его к java.util. Объект свойств передал DriverManager.getConnection или OracleDataSource.setConnectionProperties. Вы устанавливаете системное свойство включением-D опции в Вашей командной строке Java.

Java-Doracle.jdbc. V8Compatible = "истинный" MyApp Oracle JDBC 11.1 решает эту проблему. При начале с этого выпуска драйвер отображает столбцы SQL DATE на java.sql. Метка времени по умолчанию. Нет никакой потребности установить V8Compatible для получения корректного отображения. V8Compatible сильно удерживается от использования. Вы не должны использовать его вообще. При установке его на истинный, это ничего не повредит, но необходимо прекратить использовать его.

Хотя это редко использовалось тот путь, V8Compatible существовал, чтобы не назначить ДАТУ, чтобы датировать проблему, но поддерживать совместимость с 8i базы данных. 8i (и более старый) базы данных не поддерживали тип МЕТКИ ВРЕМЕНИ. Установка V8Compatible не только заставила ДАТУ SQL быть отображенной для Добавления метки времени, когда считано из базы данных, она также заставила все Метки времени быть преобразованными в ДАТУ SQL при записи в базу данных. С тех пор 8i desupported, 11.1 драйверов JDBC не поддерживают этот режим эмуляции. Поэтому V8Compatible является desupported.

Как упомянуто выше, эти 11,1 драйверов по умолчанию преобразовывают ДАТУ SQL для Добавления метки времени при чтении из базы данных. Это всегда было правильным поступком, и изменение в 9i было ошибкой. Эти 11,1 драйверов вернулись к корректному поведению. Даже если бы Вы не установили V8Compatible в своем приложении, то Вы не должны видеть различие в поведении в большинстве случаев. Можно заметить различие при использовании getObject для чтения столбца DATE. Результатом будет Метка времени, а не Дата. Так как Метка времени является подклассом Даты, это обычно не проблема. Где Вы могли бы заметить, что различие - то, при доверии преобразованию из ДАТЫ до настоящего времени для усечения компонента времени или если Вы делаете toString на значении. Иначе изменение должно быть прозрачным.

Если по некоторым причинам Ваше приложение очень чувствительно к этому изменению, и у Вас просто должно быть 9i-10g поведение, существует свойство соединения, которое можно установить. Набор mapDateToTimestamp ко лжи и драйверу вернется к значению по умолчанию 9i-10g поведение и отобразит ДАТУ до настоящего времени.

Если возможно, необходимо изменить тип столбца для ДОБАВЛЕНИЯ МЕТКИ ВРЕМЕНИ вместо ДАТЫ.

- Richard


Roger Voss записал: Я отправил следующий вопрос/проблему на stackoverflow, поэтому если бы кто-либо знает разрешение, было бы хорошо, чтобы видеть, что это ответило там:

Oracle проблема преобразования ДАТЫ SQL с помощью iBATIS через Java JDBC

Вот описание проблемы:

Я в настоящее время борюсь с Oracle sql проблема преобразования ДАТЫ с помощью iBATIS от Java.

Использую JDBC Oracle тонкая версия 10.2.0.4.0 драйвера ojdbc14. версия 2.3.2 iBATIS. Java 1.6.0_10-rc2-b32.

Проблема вращает приблизительно колонну типа ДАТЫ, который возвращается этим отрывком SQL:

ВЫБЕРИТЕ * ИЗ ТАБЛИЦЫ (pk_invoice_qry.get_contract_rate (??????????)) заказывают from_date

Вызов процедуры пакета возвращается касательно курсора, который переносится в ТАБЛИЦУ туда, где затем легко считать набор результатов, как будто был запрос Select против таблицы.

В МН Разработчике / Разработчике SQL, возвратился один из столбцов, FROM_DATE, типа ДАТЫ SQL, имеет точность ко времени суток:

Tue Dec 16 23:59:00 PST 2008

Но когда я получаю доступ к этому через iBATIS и JDBC, значение только сохраняет точность ко дню:

Tue Dec 16 12:00:00 AM PST 2008

Это более ясно при отображении как так:

Должен был быть: 1 229 500 740 000 миллисекунд с эпохи вторник, 16 декабря 2008 23:59:00 PST

Но получение этого вместо этого: 1 229 414 400 000 миллисекунд с эпохи вторник, 16 декабря 2008 0:00:00 PST (как экземпляр класса java.sql. Дата)

Независимо от того, что я пробую, я не могу выставить полную точность этого столбца DATE, который будет возвращен через Java JDBC и iBATIS.

То, от чего отображается iBATIS, является этим:

FROM_DATE: 03.12.2008: класс java.sql. Дата

Текущее отображение iBATIS - это:

Я также попробовал:

или

Но все предпринятые отображения приводят к тому же усеченному значению Даты. Это - как будто JDBC уже нанес ущерб выпуска точности данных, прежде чем iBATIS даже коснется его.

Очевидно я освобождаю часть своей точности данных путем прохождения через JDBC и iBATIS, которого не происходит, когда я остаюсь в МН рабочем Разработчике / рабочем Разработчике SQL тот же отрывок SQL как сценарий тестирования. Не приемлемый вообще, очень печальный, и в конечном счете очень страшный.

8
ответ дан 1 December 2019 в 23:32
поделиться

Я решил свою проблему с помощью jdbcType = "МЕТКА ВРЕМЕНИ" вместо jdbcType = "ДАТА"

• ПРОБЛЕМА:

• РЕШЕННЫЙ:

С уважением.

Pedro

3
ответ дан 1 December 2019 в 23:32
поделиться

Я узнал, как решить эту проблему. iBATIS разрешает пользовательским обработчикам типов быть зарегистрированными. Таким образом в моем файле sqlmap-config.xml я добавил это:

<typeAlias alias="OracleDateHandler" type="com.tideworks.ms.CustomDateHandler"/>
<typeHandler callback="OracleDateHandler" jdbcType="DATETIME" javaType="date"/>

И затем добавил этот класс, который реализует интерфейс iBATIS TypeHandlerCallback:

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

Whennever я должен отобразить ДАТУ Oracle я теперь, описывают ее как так:

<result property="from_date" jdbcType="DATETIME" javaType="date"/>
6
ответ дан 1 December 2019 в 23:32
поделиться

Проблемой является использование java.sql.Date. По данным Javadoc, значения миллисекунды, перенесенные a java.sql.Date экземпляр должен быть 'нормализован' путем установки часов, минут, секунд и миллисекунд для обнуления в зоне определенного времени, с которой экземпляр связан, для приспосабливания определению SQL DATE.

0
ответ дан 1 December 2019 в 23:32
поделиться

Да, я вижу - плоскость, которой стандарт ДАТЫ SQL должен быть, чтобы только сохранить к дневному разрешению. Действительно, вот отрывок на типе ДАТЫ Oracle:

Oracle поддерживает обе даты и времени, хотя по-другому по сравнению со стандартом SQL2. Вместо того, чтобы использовать два отдельных объекта, дату и время, Oracle только использует один, ДАТА. Тип ДАТЫ хранится в специальном внутреннем формате, который включает не только месяц, день, и год, но также и час, минуту, и второй.

Который высказывает мнение, что ДАТА Oracle превышает стандартную ДАТУ SQL.

Хм, Oracle МН народная ДАТА использования / народная ДАТА использования SQL экстенсивно для содержания значений, где они зависят от разрешения того, чтобы быть к второму. Похож на потребности iBATIS что-то как То, чтобы быть в спящем режиме sql понятие диалекта где вместо того, чтобы интерпретировать ДАТУ через java.sql. Дата, могла переопределить и вместо этого интерпретировать через java.util. Дата, которую Javadocs определяет как разрешение разрешения миллисекунды.

К сожалению, когда я изменил отображение на что-то как:

<result property="from_date" jdbcType="DATE" javaType="java.util.Date"/>

или

<result property="from_date" jdbcType="DATETIME" javaType="java.util.Date"/>

Это все еще на вид сначала перевело ДАТУ SQL в java.sql. Дата и потерянный точность времени суток.

0
ответ дан 1 December 2019 в 23:32
поделиться

Это очень распространенный вопрос; если вы используете .NET 3.5, это широко поддерживается в MiscUtil через класс Operator , который поддерживает встроенные типы и любые настраиваемые типы с операторами (включая "операторы"); в частности, это позволяет использовать с дженериками , например:

public static T Sum<T>(this IEnumerable<T> source) {
    T sum = Operator<T>.Zero;
    foreach (T value in source) {
        if (value != null) {
            sum = Operator.Add(sum, value);
        }
    }
    return sum;
}

Или в другом примере; Комплекс и все от #column_name: DATE # до #column_name: TIMESTAMP #

Итак, измените:

<result property="from_date" jdbcType="DATE" javaType="java.sql.Date"/>

на

<result property="from_date" jdbcType="TIMESTAMP" javaType="java.sql.Date"/>
1
ответ дан 1 December 2019 в 23:32
поделиться

Ричард Йи из Oracle драйверы решают проблему. Я могу это подтвердить. Была та же проблема с драйверами 10.2, обновленными сегодня до ojdbc5.jar (11.2.0.1.0), и теперь проблема исчезла.

0
ответ дан 1 December 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: