Найти в Дзене
Пионер-кофе

База данных не принимает нулевую дату. Что делать?

При разработке приложения управления временем понадобилось создавать задачи с "Неопределённым временем" Ну, не знаю я, когда нужно быть на объекте!
Даже клиент не знает.
Но чинить точно нужно. Выяснилось, что в MySQL есть такая штука, как режим sql_mode, который по умолчанию в новых версиях MySQL запрещает "нулевые" даты.
Выяснилось, что данная настройка изменяется вводом команды в SQL запрос Базы данных. SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION'; Пытливый ум заставил задаться вопросом "А что будет"
Итак: Отменить этот запрос легко.
Выполните команду: SET GLOBAL sql_mode = ''; Но лучше изначально использовать другой метод. Напугались, зато узнали много нового. Итак, лучше вообще не использовать 0000-00-00, а работать через NULL Команду можно выполнить как в phpMyAdmin, как показано на скрине выше, так и добавить в скрипты инициализации. 🔍 Что происходит при выполнении: INSERT INTO events (beginning) VALUES
Оглавление

О проблеме.

При разработке приложения управления временем понадобилось создавать задачи с "Неопределённым временем"

Ну, не знаю я, когда нужно быть на объекте!
Даже клиент не знает.
Но чинить точно нужно.
-2

Режимы баз данных

Выяснилось, что в MySQL есть такая штука, как режим sql_mode, который по умолчанию в новых версиях MySQL запрещает "нулевые" даты.

Выяснилось, что данная настройка изменяется вводом команды в SQL запрос Базы данных.

-3
SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION';

⚠️ Потенциальные риски

Пытливый ум заставил задаться вопросом "А что будет"
Итак:

  1. STRICT_TRANS_TABLES может сломать старые приложения, которые полагаются на неявные преобразования типов.
  2. ONLY_FULL_GROUP_BY требует явного перечисления полей при использовании метода GROUP BY (*)
-4

Данные команды вносят следующие изменения:

  1. ONLY_FULL_GROUP_BY
    Запрещает неоднозначные запросы с GROUP BY
    Пример риска: SELECT a, b FROM t GROUP BY a (b не в GROUP BY)
  2. STRICT_TRANS_TABLES
    Строгая проверка типов данных
    Пример риска: Вставка строки в числовое поле вызовет ошибку вместо предупреждения
  3. ERROR_FOR_DIVISION_BY_ZERO
    Ошибка при делении на ноль (вместо NULL)
    Пример: SELECT 1/0 → ошибка
  4. NO_ENGINE_SUBSTITUTION
    Запрещает автоматическую замену движка таблиц
    Пример: Если указан InnoDB, но он недоступен → ошибка вместо использования MyISAM

Отмена команды

Отменить этот запрос легко.
Выполните команду:

SET GLOBAL sql_mode = '';

Но лучше изначально использовать другой метод.

Безопасный и современный метод

Напугались, зато узнали много нового.

Итак, лучше вообще не использовать 0000-00-00, а работать через NULL

-5

Команду можно выполнить как в phpMyAdmin, как показано на скрине выше, так и добавить в скрипты инициализации.

🔍 Что происходит при выполнении:

  1. Структурное изменение
    MySQL изменяет только метаданные таблицы, разрешая
    NULL значения, но не трогает существующие записи.
  2. Сохранение данных
    Все ранее записанные даты (включая
    0000-00-00 00:00:00) останутся как есть (если в таблице уже есть нулевые даты, они не превратятся в NULL. Это разные значения)
  3. Новые возможности
    Теперь можно явно записывать
    NULL:
INSERT INTO events (beginning) VALUES (NULL); -- Теперь допустимо

🔄 Как преобразовать существующие нулевые даты в NULL

Если нужно заменить все 0000-00-00 на NULL, то необходимо просто выполнить команду

UPDATE events SET beginning = NULL WHERE beginning = '0000-00-00 00:00:00';

Но учтите, что скрипты нужно перепроверять. Повторюсь: NULL и 0000 это не одно и то же.

💡 Особенности оформления запросов

Ну и конечно же, вопрос "А как фильтровать"
На скрине ниже всё ясно.

-6

Что ещё почитать

И NULL и 0000-00-00 индексируются.
INDEX это механизм ускорения поиска в больших объёмах информации.
Просвещайтесь.

Ниже приведу команды для баз данных отличных от mySQL

Если вы работаете с SQL Server, для изменения колонки воспользуйтесь командой ALTER COLUMN:

ALTER TABLE ИмяТаблицы
ALTER COLUMN ИмяКолонки ТипДанных NULL;

В PostgreSQL для отключения ограничения NOT NULL используйте такую структуру:

ALTER TABLE имя_таблицы
ALTER COLUMN имя_колонки DROP NOT NULL;

(NOT NULL: Это условие ограничивает поле от оставания без значения)

В Oracle тоже подходит вариант с командой MODIFY:

ALTER TABLE имя_таблицы
MODIFY (имя_колонки NULL);