Я недавно принял старый проект, который был создан 10 лет назад. Он использует MySQL 5.1.
Помимо прочего, мне нужно изменить набор символов по умолчанию с latin1 на utf8.
В качестве примера у меня есть такие таблицы:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`last_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`username` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`email` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`pass` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`active` char(1) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'Y',
`created` datetime NOT NULL,
`last_login` datetime DEFAULT NULL,
`author` varchar(1) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT 'N',
`locked_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`ripple_token` varchar(36) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`ripple_token_expires` datetime DEFAULT '2014-10-31 08:03:55',
`authentication_token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_users_on_reset_password_token` (`reset_password_token`),
UNIQUE KEY `index_users_on_confirmation_token` (`confirmation_token`),
UNIQUE KEY `index_users_on_unlock_token` (`unlock_token`),
KEY `users_active` (`active`),
KEY `users_username` (`username`),
KEY `index_users_on_email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=1677 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC
Я настроил свой собственный Mac для работы над этим. Не слишком задумываясь, я запустил «brew install mysql», который установил MySQL 5.7. Таким образом, у меня есть некоторые конфликты версий.
Я скачал копию этой базы данных и импортировал ее.
Если я попытаюсь выполнить запрос, как это:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
Я получаю эту ошибку:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Я думал, что смогу это исправить с помощью:
ALTER TABLE users MODIFY created datetime NULL DEFAULT '1970-01-01 00:00:00';
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
но я получаю:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ;
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Нужно ли обновлять каждое значение?
Я не смог сделать это:
(на MySQL 5.7.13).
Я продолжал получать
Incorrect datetime value: '0000-00-00 00:00:00'
ошибку.Странно, это сработало
SELECT * FROM users WHERE created = '0000-00-00 00:00:00'
. Я понятия не имею, почему первый отказывает, а второй работает ... может быть, ошибка MySQL?В любом случае этот запрос UPDATE работал:
источник
UPDATE users SET created = NULL WHERE created = '0'
entity
WHERE creationAt = "0000-00-00 00:00:00" работает нормально, но с обновленной ошибкой! У меня такая же проблема. Исправить это с помощью решения @obe CAST (созданного как CHAR (20)) ... Я думаю, что это ошибка.UPDATE users SET created = NULL WHERE created=0
(без 'около нуля)Изменение значения по умолчанию для столбца с
ALTER TABLE
оператором, например... не изменяет значения, которые уже сохранены. Значение «по умолчанию» применяется к вставляемым строкам, для которых значение не указывается для столбца.
Что касается того, почему вы сталкиваетесь с ошибкой, вполне вероятно, что
sql_mode
настройка для вашего сеанса включаетNO_ZERO_DATE
.Ссылка: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
Когда вы выполняли «импорт», операторы SQL, которые выполняли INSERT в этой таблице, выполнялись в сеансе, в котором допускались нулевые даты.
Чтобы увидеть настройку sql_mode:
-или-
Что касается того, как «исправить» текущую проблему, чтобы ошибка не возникала при запуске
ALTER TABLE
оператора.Несколько вариантов:
1) измените,
sql_mode
чтобы разрешить нулевые даты, удаливNO_ZERO_DATE
иNO_ZERO_IN_DATE
. Изменение можно применить в файле my.cnf, поэтому после перезапуска MySQL Serversql_mode
переменная будет инициализирована с настройкой в my.cnf.Для временного изменения мы можем изменить настройку за один сеанс, не требуя глобального изменения.
2) изменить
created
столбец, чтобы разрешить значения NULL, и обновить существующие строки, чтобы изменить нулевые даты на нулевые значения3) обновить существующие строки, чтобы изменить нулевые даты на действительные даты
Нам не нужно запускать отдельные операторы для обновления каждой строки. Мы можем обновить все строки одним махом (при условии, что это таблица разумного размера. Для таблицы большего размера, чтобы избежать огромного отката / отмены генерации, мы можем выполнить операцию в кусках разумного размера.)
В этом вопросе
AUTO_INCREMENT
значение, показанное для определения таблицы, гарантирует, что количество строк не является чрезмерным.Если мы уже изменили
created
столбец для учетаNULL
значений, мы можем сделать что-то вроде этого:Или мы можем установить их на действительную дату, например, 2 января 1970 г.
(Обратите внимание, что значение datetime полуночи 1 января 1970 года (
'1970-01-01 00:00:00'
) является «нулевой датой». Это будет оценено как'0000-00-00 00:00:00'
источник
sql_mode
. Более поздние версии MySQL имеют настройки по умолчанию,sql_mode
которые являются более строгими, чем предыдущие версии. Ссылка на 8,0 здесь: dev.mysql.com/doc/refman/8.0/en/sql-mode.html смNO_ZERO_DATE
,ALLOW_INVALID_DATE
и др. обратите внимание, что некоторые из них включены в режим STRICT, напримерSTRICT_TRANS_TABLES
,STRICT_ALL_TABLES
и другие комбинированные режимы. Чтобы обойти ограничения, временно измените sql_mode для сеансаЯ получил это исправить, выполнив это до запроса
источник
Согласно справочному руководству по MySQL 5.7 :
Поскольку
0000-00-00 00:00:00
недопустимоеDATETIME
значение, ваша база данных повреждена. Вот почему MySQL 5.7 - который поставляется сNO_ZERO_DATE
включенным режимом по умолчанию - выдает ошибку при попытке выполнить операцию записи.Вы можете исправить свою таблицу, обновив все недопустимые значения до любого другого допустимого значения, например
NULL
:Также, чтобы избежать этой проблемы, я рекомендую вам всегда устанавливать текущее время в качестве значения по умолчанию для ваших
created
похожих полей, чтобы они автоматически заполнялисьINSERT
. Просто сделать:источник
источник
Вот какое у меня решение PhpMyAdmin / Fedora 29 / MySQL 8.0 (например):
set sql_mode='SOMETHING';
не работает , вызов команды выполнен успешно, но ничего не изменилось.set GLOBAL sql_mode='SOMETHING';
изменить глобальную конфигурацию постоянное изменение.set SESSION sql_mode='SOMETHING';
Изменение конфигурации сеанса Переменная SESSION влияет только на текущего клиента.https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
Итак, я делаю это:
SHOW VARIABLES LIKE 'sql_mode';
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
NO_ZERO_IN_DATE,NO_ZERO_DATE
set GLOBAL SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
Вы можете удалить или добавить другой режим таким же образом.
Это полезно для изменения глобальных параметров для использования и тестирования сред, или в каждом файле или группе запросов должен быть указан sql_mode.
Адаптировано из вопроса, задаваемого здесь: how-can-i-disable-mysql-strict-mode
Пример: установить последний контент Joomla 4.0-alpha.
Изменить: в PhpMyadmin, если у вас есть контроль над сервером, вы можете изменить
sql_mode
(и все остальные параметры) непосредственно вPlus > Variables > sql_mode
источник
Вы можете изменить тип создаваемого поля с
datetime
наvarchar(255)
, затем вы можете установить (обновить) все записи, которые имеют значение"0000-00-00 00:00:00"
дляNULL
.Теперь вы можете делать ваши запросы без ошибок. После того, как вы закончите, вы можете изменить тип поля, созданного для
datetime
.источник
У меня эта ошибка также после обновления MySQL с 5.6 до 5.7
Я понял, что лучшим решением для меня было объединить некоторые решения здесь и сделать что-то такое, что работало бы с минимальными затратами.
Я использую MyPHPAdmin для простоты отправки запросов через интерфейс, потому что тогда я могу легко проверить структуру и все такое. Вы можете использовать ssh напрямую или другой интерфейс. Метод должен быть похожим или одинаковым в любом случае.
...
1.
Сначала проверьте фактическую ошибку при попытке восстановить базу данных:
Это говорит мне о том, что столбцу check_out_time в таблице jos_menu необходимо исправить все неверные даты, а также изменить «по умолчанию».
...
2.
Я запускаю SQL-запрос на основе информации в сообщении об ошибке:
Если вы получили ошибку, вы можете использовать приведенный ниже запрос, который, кажется, всегда работает:
...
3.
После этого я запускаю второй SQL-запрос:
Или в случае, если это дата, которая должна быть NULL
...
Если я запускаю базу данных восстановления сейчас, я получаю:
joomla.jos_menu ОК
...
Работает просто отлично :)
источник
Проверьте
если вы видите там материал 'ZERO_DATE', попробуйте
Выйдите и снова войдите в свой клиент (это странно) и попробуйте снова
источник
Сделайте режим sql не строгим
при использовании laravel перейдите в config-> database, перейдите в настройки mysql и установите строгий режим в false
источник
У меня была похожая проблема, но в моем случае в какой-то строке было значение NULL.
Итак, сначала я обновляю таблицу:
проблема решена, по крайней мере, в моем случае.
источник
Я тоже получил
информация об ошибке
Исправьте это, изменив
0000-00-00 00:00:00
на1970-01-01 08:00:00
1970-01-01 08:00:00
метка времени unix равна 0источник
NO_ZERO_DATE
Я нашел решение по адресу https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-SQL-mode-in-MySQL . У меня было это:
Обратите внимание на
NO_ZERO_IN_DATE,NO_ZERO_DATE
результаты выше. Я удалил это, сделав это:Тогда у меня было это:
После этого я мог
ALTER TABLE
успешно использовать и изменять свои таблицы.источник
Это то, что я сделал, чтобы решить мою проблему. Я тестировал в локальном MySQL 5.7 Ubuntu 18.04.
Перед глобальным выполнением этого запроса я добавил файл cnf в каталог /etc/mysql/conf.d . Имя файла cnf : mysql.cnf и коды
Затем я перезапустить MySQL
Надеюсь, это может кому-то помочь.
источник
NO_ENGINE_SUBSTITUTION
находится во всех столбцах,SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;
но все равно я получаю сообщение об ошибке для недопустимой даты и времени,0000-00-00 00:00:00
пока не выполню первый запрос еще раз.set global sql_mode="NO_ENGINE_SUBSTITUTION";
Есть идеи?NO_ZERO_IN_DATE,NO_ZERO_DATE
в вашей версии строку my.ini, определяющуюsql_mode
.Это невероятно некрасиво, но и быстро решило проблему для меня. Ваша таблица нуждается в уникальном ключе, который вы будете использовать для исправления испорченных столбцов. В этом примере первичный ключ называется «id», а поврежденный столбец меток времени - «BadColumn».
Выберите идентификаторы испорченных столбцов.
select id from table where BadColumn='0000-00-00 00:00:00'
Соберите идентификаторы в строку через запятую. Пример:
1, 22, 33
. Я использовал для этого внешнюю оболочку (скрипт Perl), чтобы быстро выплюнуть их все.Используйте свой список идентификаторов, чтобы обновить старые столбцы с правильной датой (с 1971 по 2038 год).
update table set BadColumn='2000-01-01 00:00:00' where id in (1, 22, 33)
источник
Мое решение
источник
Вместо того
использование
источник
Если вы вводите данные вручную, вы можете удалить значения и нули на TIMESTAMP (6) .000000, чтобы он стал TIMESTAMP. Это работало хорошо со мной.
источник