Ошибка в mysql при установке значения по умолчанию для DATE или DATETIME
Я запускаю MySql Server 5.7.11 и это предложение:
updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
работает не. Предоставление ошибки:
ERROR 1067 (42000): Invalid default value for 'updated'
Но следующее:
updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'
просто работает.
В том же случае для DATE.
Как побочный элемент, он упоминается в mysql docs:
Тип DATE используется для значений с частью даты, но без временной части. MySQL извлекает и отображает значения DATE в формате "YYYY-MM-DD". Поддерживаемый диапазон - от "1000-01-01" до "9999-12-31".
даже если они также говорят:
Недействительные значения DATE, DATETIME или TIMESTAMP преобразуются в нулевое значение соответствующего типа ('0000-00-00' или '0000-00-00 00:00:00').
Также учитывая вторую цитату из документации mysql, может ли кто-нибудь сообщить мне, почему она дает эту ошибку?
Ответы
Ответ 1
Ошибка возникает из-за режима sql, который может быть строгим в соответствии с последней документацией MYSQL 5.7.
Документация MySQL 5.7 говорит:
Строгий режим влияет на то, разрешает ли серверу "0000-00-00" в качестве действительной даты: Если строгий режим не включен, допускается "0000-00-00" , а вставки не выдают никаких предупреждений. Если включен строгий режим, "0000-00-00" не разрешен, и вставки создают ошибку, если не указано IGNORE. Для INSERT IGNORE и UPDATE IGNORE разрешено "0000-00-00" , а вставки выдают предупреждение.
Проверить режим MYSQL
SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session
Отключение режима STRICT_TRANS_TABLES
Однако, чтобы разрешить формат 0000-00-00 00:00:00
, вы должны отключить режим STRICT_TRANS_TABLES в файле конфигурации mysql или командой
По команде
SET sql_mode = '';
или
SET GLOBAL sql_mode = '';
Использование ключевого слова GLOBAL
требует суперпревалирования и влияет на операции, с которыми все клиенты соединяются с этого времени на
если выше не работает, чем перейти к /etc/mysql/my.cnf
(согласно ubuntu) и прокомментировать STRICT_TRANS_TABLES
Кроме того, если вы хотите окончательно установить режим sql при запуске сервера, включите SET sql_mode=''
в my.cnf
в Linux или MacOS. Для окон это должно быть сделано в файле my.ini
.
Примечание
Однако строгий режим не включен по умолчанию в MYSQL 5.6. Следовательно, он не создает ошибку в соответствии с документацией MYSQL 6, в которой говорится
MySQL позволяет вам хранить "нулевое" значение "0000-00-00" в качестве "фиктивной даты". Это в некоторых случаях более удобно, чем использование значений NULL, и использует меньше пространства данных и индексов. Чтобы запретить "0000-00-00" , включите режим NO_ZERO_DATE SQL.
UPDATE
Что касается вопроса об ошибке, как сказал @Dylan-Su:
Я не думаю, что это ошибка, так как MYSQL развивается за время, из-за чего некоторые вещи меняются в зависимости от дальнейшего улучшения продукта.
Однако у меня есть еще один связанный отчет об ошибке в отношении функции NOW()
Поле Datetime не принимает значение по умолчанию NOW()
Другая полезная нота. Автоматическая инициализация и обновление для TIMESTAMP и DATETIME]
Начиная с MySQL 5.6.5, столбцы TIMESTAMP и DATETIME могут быть автоматически инициализированы и обновлены до текущей даты и времени (то есть текущей метки времени). До 5.6.5 это верно только для TIMESTAMP и не более одного столбца TIMESTAMP для каждой таблицы. Следующие примечания сначала описывают автоматическую инициализацию и обновление для MySQL 5.6.5 и выше, затем различия для версий, предшествующих 5.6.5.
Обновление в отношении NO_ZERO_DATE
В MySQL с 5.7.4 этот режим устарел. Для предыдущей версии вы должны прокомментировать соответствующую строку в файле конфигурации. Обратитесь Документация MySQL 5.7 по NO_ZERO_DATE
Ответ 2
У меня была эта ошибка с WAMP 3.0.6 с MySql 5.7.14.
Решение:
измените строку 70 (если ваш INI файл нетронутым) в файле c:\wamp\bin\mysql\mysql5.7.14\my.ini
из
sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
в
sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
и перезапустите все службы.
Это отключит строгий режим. Согласно документации, "строгий режим" означает режим с STRICT_TRANS_TABLES
или STRICT_ALL_TABLES
или с STRICT_ALL_TABLES
. Документация гласит:
"Режим SQL по умолчанию в MySQL 5.7 включает в себя следующие режимы: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER и NO_ENGEN.
Ответ 3
Я попал в ситуацию, когда данные смешивались между NULL и 0000-00-00 для поля даты. Но я не знал, как обновить "0000-00-00" до NULL, потому что
update my_table set my_date_field=NULL where my_date_field='0000-00-00'
больше не разрешено Мой обходной путь был довольно прост:
update my_table set my_date_field=NULL where my_date_field<'1000-01-01'
потому что все неправильные значения my_date_field
(правильные даты или нет) были до этой даты.
Ответ 4
Проблема с синтаксисом конфигурации
В некоторых версиях MYSQL (проверенных 5.7. *) в системах * nix вы должны использовать этот синтаксис:
[mysqld]
sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"
Они не будут работать:
тире без кавычек
sql-mode=NO_ENGINE_SUBSTITUTION
подчеркнуть отсутствие кавычек
sql_mode=NO_ENGINE_SUBSTITUTION
подчеркивание и кавычки
sql_mode="NO_ENGINE_SUBSTITUTION"
Более полный обзор конфигурационных значений и sql-режима:
Как установить постоянные флаги режима Sql
Ответ 5
Просто добавьте строку: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
внутри файла: /etc/mysql/mysql.conf.d/mysqld.cnf
то sudo service mysql restart
Ответ 6
Сначала выберите текущий сеанс sql_mode
:
SELECT @@SESSION.sql_mode;
Затем вы получите что-то вроде значение по умолчанию:
'ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
а затем установите sql_mode
без 'NO_ZERO_DATE'
:
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Если у вас есть гранты, вы можете сделать это и для GLOBAL
:
SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
Ответ 7
Он работает для 5.7.8:
mysql> create table t1(updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00');
Query OK, 0 rows affected (0.01 sec)
mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.8-rc |
+-----------+
1 row in set (0.00 sec)
Вы можете создать SQLFiddle для воссоздания вашей проблемы.
http://sqlfiddle.com/
Если он работает для MySQL 5.6 и 5.7.8, но не работает 5.7.11. Тогда это, вероятно, будет ошибкой регрессии для 5.7.11.
Ответ 8
Этот ответ это только для MySQL 5.7:
На самом деле, лучше всего не указывать значение sql_mode, а использовать в PHP переменную сеанса с:
SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
Так что, по крайней мере, вы сохраняете другие значения по умолчанию.
Это безумие, что документация mysql не ясна, вам нужно удалить значения по умолчанию в sql_mode:
NO_ZERO_IN_DATE, NO_ZERO_DATE, я понимаю, но в будущих версиях это будет прекращено.
STRICT_ALL_TABLES, с этим, до того, как параметры будут игнорироваться, поэтому вам нужно удалить его тоже.
Наконец, тоже TRADITIONAL, но документация говорит об этом параметре: "выдавать ошибку вместо предупреждения" при вставке неверного значения в столбец ", с этим параметром даты с нулевыми значениями не вставляются, но без да.
MySQL не очень организован с этими параметрами и комбинациями.
Ответ 9
Чтобы решить проблему с MySQL Workbench (после применения решения на стороне сервера):
Удалите SQL_MODE в TRADITIONAL на панели настроек.
![введите описание изображения здесь]()
Ответ 10
Комбинации опций для mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64)
.
Не бросает:
STRICT_TRANS_TABLES
+ NO_ZERO_DATE
Броски:
STRICT_TRANS_TABLES
+ NO_ZERO_IN_DATE
Мои настройки в /etc/mysql/my.cnf
на Ubuntu:
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Ответ 11
set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';