'0000-00-00 00:00:00' не може бути представлено як помилка java.sql.Timestamp


141

У мене є база даних із датами

 (`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'). 

Я використовую MySQL. З програми інколи дані передаються без дати в базу даних. Отже, значення дати автоматично присвоюється, 0000-00-00 00:00:00 коли дані таблиці вказуються з стовпцем дати, воно дає помилку

...'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp.......

Я намагався передати нульове значення даті при вставці даних, але воно отримує призначення поточному часу.

Чи є спосіб, як я можу отримати, ResultSetне змінюючи структуру таблиці?

Відповіді:


302

Ви можете використовувати цю URL-адресу JDBC безпосередньо у конфігурації джерела даних:

jdbc: mysql: // yourserver: 3306 / yourdatabase? zeroDateTimeBehavior = convertToNull


2
цікавий. Читаючи інші відповіді, так, нуль місяця немає. Що це насправді означає?
Туфір

2
Чи знаєте ви, чи є еквівалент MariaDB для додавання до моєї URL-адреси jdbc? jdbc: mariadb: // localhost: 3306 / dev? zeroDateTimeBehavior = convertToNull, здається, не працює для мене.
jeffkempf

Мав бути CONVERT_TO_NULL для мене
routeburn

16

Незалежно від того, чи є "дата" 0000-00-00 "дійсною" датою ", питання не має значення." Просто змінити базу даних "рідко є прийнятним рішенням.

Факти:

  • MySQL дозволяє дату зі значенням нулів.
  • Ця "особливість" користується широким застосуванням з іншими мовами.

Отже, якщо я "просто зміню базу даних", тисячі рядків PHP-коду зірвуться.

Програмістам Java потрібно прийняти нульову дату MySQL і їм потрібно повернути нульову дату в базу даних, коли інші мови покладаються на цю "функцію".

Програміст, який підключається до MySQL, повинен обробляти нульові і 0000-00-00, а також дійсні дати. Зміна 0000-00-00 на null не є життєздатним варіантом, оскільки тоді ви більше не можете визначити, чи очікувалася дата для 0000-00-00 для повернення в базу даних.

Для 0000-00-00 я пропоную перевірити значення дати як рядок, а потім змінити його на ("y", 1) або ("yyyy-MM-dd", 0001-01-01), або на інший недійсний Дата MySQL (менше 1000 року, iirc). У MySQL є ще одна "особливість": низькі дати автоматично перетворюються на 0000-00-00.

Я усвідомлюю, що моя пропозиція - це хитрощі. Але це стосується обробки дати MySQL. І два глузди не роблять це правильно. Справа в тому, що багатьом програмістам доведеться назавжди обробляти нульові дати MySQL .


9

Додайте наступне твердження до протоколу JDBC-mysql:

?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

наприклад:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

5
Будьте обережні з таким підходом. Це працює як шарм, але він зняв на нас сервер виробництва (працював ідеально у розробниках, хоча ...). Що ми дізналися, це те, що вам потрібно буде цитувати рядок, оскільки & в деяких контекстах інтерпретується як особливий символ, що надає рядку зовсім інше значення ...
Techmag

6

Замість використання фальшивих дат, таких як 0000-00-00 00:00:00або 0001-01-01 00:00:00(останні слід прийняти, оскільки це дійсна дата), змініть схему бази даних, щоб дозволити NULLзначення.

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL

3

Як розширений поворот, коли ви не можете змінити стовпець дати або оновити значення, або під час цих змін, ви можете зробити вибір, використовуючи випадок / коли.

SELECT CASE ModificationDate WHEN '0000-00-00 00:00:00' THEN '1970-01-01 01:00:00' ELSE ModificationDate END AS ModificationDate FROM Project WHERE projectId=1;

1

Я боровся з цією проблемою та застосував рішення щодо конкатенації URL-адрес, внесений @Kushan у прийнятій відповіді вище. Він працював у моєму локальному екземплярі MySql. Але коли я розгорнув додаток Play / Scala в Heroku, він більше не працюватиме. Heroku також об'єднує кілька аргументів у URL-адресу БД, яку вони надають користувачам, і це рішення, через те, що Heroku використовує конкатенацію "?" перед власним набором аргументів не вийде. Однак я знайшов інше рішення, яке, здається, працює однаково добре.

SET sql_mode = 'NO_ZERO_DATE';

Я помістив це в описи таблиці, і це вирішило проблему "0000-00-00 00:00:00" не може бути представлена ​​як java.sql.Timestamp


1

ви можете спробувати так

ArrayList<String> dtlst = new ArrayList<String>();
String qry1 = "select dt_tracker from gs";

Statement prepst = conn.createStatement();
ResultSet rst = prepst.executeQuery(qry1);
while(rst.next())
{
    String dt = "";
    try
    {
        dt = rst.getDate("dt_tracker")+" "+rst.getTime("dt_tracker");
    }
    catch(Exception e)
    {
        dt = "0000-00-00 00:00:00";
    }

    dtlst.add(dt);
}

0

Не було року 0000 і немає місяця 00 або дня 00. Я пропоную вам спробувати

0001-01-01 00:00:00

Хоча рік 0 визначений у деяких стандартах, він швидше заплутаний, ніж корисний IMHO.


2
Так, рік 0000. інфактний його рік 0, а у нас рік -1 і рік -1000. Ніколи не бачив цього григоріанського календаря чи цієї Анно-Доміні, і ще більше, особливо для григоріанського календаря немає нуля року, але ізо має і ізо використовується бі-комп’ютери див. 0 рік
botenvouwer

@sirwilliam Дякую за цікаву кваліфікацію. Здається, що ОП, що хотів, щоб рік 0 розглядався як NULL або щось, що не існує.
Пітер Лоурі

1
У MySQL 0000-00-00 00:00:00 дорівнює 0. У застарілому коді можуть бути деякі запити, які покладаються на це.
Juha Palomäki


0

Я знаю, що це буде пізньою відповіддю, проте ось найправильніша відповідь.

У базі даних MySQL змініть timestampзначення за замовчуванням на CURRENT_TIMESTAMP. Якщо у вас є старі записи з підробленим значенням, вам доведеться їх вручну виправити.


це також не допоможе.
Суніл Шарма

0

Ви можете видалити властивість "not null" зі свого стовпця в таблиці mysql, якщо немає необхідності. коли ви видалите властивість "not null", немає необхідності в перетворенні "0000-00-00 00:00:00", і проблеми вже немає.

Принаймні працював для мене.


-2

Я вважаю, що це допомога в повному обсязі для тих, хто отримує це нижче. Виняток щодо завантаження даних через logstash Помилка: logstash.inputs.jdbc - Виняток при виконанні запиту JDBC {: виключення => #}

Відповідь: jdbc: mysql: // localhost: 3306 / database_name? ZeroDateTimeBehavior = convertToNull "

або якщо ви працюєте з mysql

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.