миграция приложения oracle в значение поля даты / времени postgresql вне диапазона: 1400-02-29 00:00:00 AD

Я переношу приложение с Oracle на Postgresql. В одной из функций, которые я уже перенес, я копирую данные из другой базы данных Oracle (ссылка на базу данных в Oracle, расширение oracle_fdw в postgresql) из нескольких таблиц в локальную таблицу в моей базе данных postgresql. Однако я получаю следующую ошибку:

 NOTICE:  Insert data into table from remote table : insert into IP_MAN 
 select * from IP_MAN_production
 NOTICE:     PROCEDURE copy_table : V_Step = 4 // **SQLERRM = date/time field 
 value out of range: "1400-02-29 00:00:00 AD"**
 CONTEXT:  converting column "birthday" for foreign table scan of "ip_man_production", 
 row 32481

Когда я пытаюсь выбрать конкретную строку в Oracle db, я получаю следующее значение:

select date from bezeq.ip_manuim where 
birthday=to_date('29/02/1400','dd/mm/yyyy');

  birthday
  --------
 01010001

день рождения - тип данных - метка времени без часового пояса.

Любая идея ?


person JeyJ    schedule 24.07.2017    source источник
comment
Случайно ли дни рождения записываются только с указанием месяца и числа, а не года? Если это так, UPDATE запрос, устанавливающий их годы на 2000, может решить вашу проблему, если месяц и дата имеют значение.   -  person coladict    schedule 24.07.2017
comment
большинство значений в этом столбце имеют формат дд / мм / ггггг, но, как вы можете видеть, я упомянул результат, который я получил, когда выбрал таблицу.   -  person JeyJ    schedule 24.07.2017
comment
Вы предоставили нам выходные данные поля date, но birthdate является проблематичным.   -  person coladict    schedule 24.07.2017
comment
нет нет, я написал дату но я ошибся - это был день рождения   -  person JeyJ    schedule 24.07.2017
comment
Привет, я обновил значение, и это устранило мою проблему. Спасибо !   -  person JeyJ    schedule 24.07.2017


Ответы (1)


PostgreSQL считает, что 1400 год не был високосным.

См. Это определение в src/include/utils/datetime.h:

/*
 * These are the rules for the Gregorian calendar, which was adopted in 1582.
 * However, we use this calculation for all prior years as well because the
 * SQL standard specifies use of the Gregorian calendar.  This prevents the
 * date 1500-02-29 from being stored, even though it is valid in the Julian
 * calendar.
 */
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

Как говорится в комментарии, отклонять 1400-02-29 технически неправильно, но это оправдано расплывчатым упоминанием стандарта SQL. Я не знаю, верен ли этот аргумент, но я не буду копать глубже, поскольку кажется, что вы решили свою проблему.

person Laurenz Albe    schedule 24.07.2017
comment
Действительно, я решил свою проблему. Так что технически я не могу вставить дату до 1582 года в таблицы postgresql? - person JeyJ; 25.07.2017
comment
Вы абсолютно можете вставлять даты до 4713 г. до н.э., но PostgreSQL будет обрабатывать високосные годы в соответствии с григорианским календарем, хотя в юлианском календаре, который действовал до 1582 года, каждый четвертый год был високосным (что привело к смещению сезонов вперед). Но все это, хотя и волнует любого, кто склонен к мазохизму, вероятно, не имеет значения для вашего варианта использования. - person Laurenz Albe; 25.07.2017