Гость
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как вылечить битую дату? / 8 сообщений из 8, страница 1 из 1
04.11.2021, 01:36
    #40109132
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
Есть база-источник MySQL
я читаю из таблицы тулзом используя JDBC драйвер, тулз падает на чтении поля даты с ошибкой java на аргумент MONTH YEAR и тп

в таблице есть поле date и в нем попадаются кривые даты, как минимум вида 0001-09-28
пролистать глазами невозможно, там десятки миллионов записей

конструкция вида where datefield is not null не работает вообще, даже в клиенте, т.е. выборка все равно выдает строки где поле null
это вообще отдельная жесть

я пытался отбросить кривые даты так, не помогло
if(STR_TO_DATE(DATE_FORMAT(datefield,'%Y-%m-%d %H:%i:%S'),'%Y-%m-%d %H:%i:%S') is not null, datefield,null) as datefield

т.е. запрос вида
select if(STR_TO_DATE(DATE_FORMAT(datefield,'%Y-%m-%d %H:%i:%S'),'%Y-%m-%d %H:%i:%S') is not null, datefield, null) from tablename
where id>4500000
and DATE_FORMAT(datefield,'%Y')<1900 and datefieldis is not null

возвращает
null
null
0001-05-06
null
0001-07-08
null

еще нашел, что в поле есть значения '0000-00-00' драйвер клиента вопит об ошибке, но поиск количества таких строк по условию
='0000-00-00' работает и выдает некую разумную цифру

как можно прочекать корректность даты?
...
Рейтинг: 0 / 0
04.11.2021, 04:35
    #40109142
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
а самое интересное это одна строка где
select datefield,DATE_FORMAT(datefield,'%Y-%m-%d') выдает
2000-05-01 2000-04-31

это как? и на этой строке валится JDBC драйвер
что реально в поле? как это поймать?
условие datefield = DATE_FORMAT(datefield,'%Y-%m-%d') не работает и выдает true
...
Рейтинг: 0 / 0
04.11.2021, 05:24
    #40109144
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
в апреле же 30 дней, т.е. кто-то умудрился запихнуть в поле невалидную дату
она отображается в клиенте как ближайшая валидна, но на самом деле кривая, и все функции конвертации на ней глючат
...
Рейтинг: 0 / 0
04.11.2021, 06:15
    #40109145
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
в доке типа пример, но он не рабочий
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date

Код: sql
1.
2.
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
        -> '2004-04-31'



реально показывает null и генерит ошибку, но Null не настоящий если присмотреться

An error occurred while executing or fetching the data:
Error getting value for: 1/1: java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date

If the date, time, or datetime value extracted from str is illegal, STR_TO_DATE() returns NULL and produces a warning.

select if(STR_TO_DATE('2000-04-31','%Y-%m-%d') is null,0, 1)
1

а реально возвращает кривую дату
select if(STR_TO_DATE('2000-04-31','%Y-%m-%d')='2000-04-31',0, 1)
0

вроде вот такая конструкция работает и позволяет вместо грязи ставить NULL
if(DAYNAME(CAST(datefieldAS char(10))) is null, null, datefield)

вообще то странно для базы позволять заливать невалидные данные
...
Рейтинг: 0 / 0
04.11.2021, 10:38
    #40109159
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
уже думал, что победил, но нет, оказывается если год 0001 то это тоже беда
year(datefield) и DATE_FORMAT(datefield,'%Y')
возвращают 0 и JDBC снова падает
нужно добавлять условие DATE_FORMAT(datefield,'%Y')<1900
...
Рейтинг: 0 / 0
04.11.2021, 13:26
    #40109196
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
Sintetik
вообще то странно для базы позволять заливать невалидные данные
Это настраивается.
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html ALLOW_INVALID_DATES

Do not perform full checking of dates. Check only that the month is in the range from 1 to 12 and the day is in the range from 1 to 31. This may be useful for Web applications that obtain year, month, and day in three different fields and store exactly what the user inserted, without date validation. This mode applies to DATE and DATETIME columns. It does not apply TIMESTAMP columns, which always require a valid date.

With ALLOW_INVALID_DATES disabled, the server requires that month and day values be legal, and not merely in the range 1 to 12 and 1 to 31, respectively. With strict mode disabled, invalid dates such as '2004-04-31' are converted to '0000-00-00' and a warning is generated. With strict mode enabled, invalid dates generate an error. To permit such dates, enable ALLOW_INVALID_DATES.
...
Рейтинг: 0 / 0
04.11.2021, 13:32
    #40109199
Sintetik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
база не моя, досталась как готовый источник, но зачем вообще позволять делать такую настройку, да еще я подозреваю по умолчанию из коробки? Такое вообще нельзя позволять ни настраиваемо ни вообще никак.
...
Рейтинг: 0 / 0
04.11.2021, 13:52
    #40109203
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как вылечить битую дату?
Sintetik
как это поймать?
Судя по цитате из доке "It does not apply TIMESTAMP columns, which always require a valid date." можно попробовать преобразовать к TIMESTAMP и обратно.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как вылечить битую дату? / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]