我最近接手了一个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

我必须更新每个值吗?


当前回答

通读这些答案,我尝试了很多,但没有任何变化。还是会得到错误。

我研究了一下,找到了一个真正有效的方法;至少对我来说。但如果它对我有效,它很可能对每个人都有效。因为我永远找不到答案!哈哈

我使用的是Ubuntu 18.04,但我使用过其他Linux操作系统,如Fedora,直进Linux, XAMPP, yadda。他们的档案似乎都是一样的。我也使用MySQL版本5.7.37-0。

在Ubuntu上,我进入/etc/mysql/。在那里,你有几个conf文件,但你想要的是my.cnf。

在my.cnf中,您将有一个标记为[mysqld]的部分。就在这下面(我把它放在其他任何东西之前),你会输入以下内容:

sql_mode="ONLY_FULL_GROUP_BY,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

重新启动MySQL服务器,您应该不再收到这个错误。

这是长久之计。有一个临时解决方案,输入SQL命令——

设置sql_mode = " ";

——在你的INSERT或UPDATE QUERY之前,它包含date或datetime值,如' 0000-00-00 00:00:00 ',但这是一个临时解决方案,仍然保留在当前会话中,你必须在下次登录时再次输入它,并遇到同样的问题。

所以,永久的解决方案似乎是可行的。

其他回答

这就是我解决问题的方法。我在本地MySQL 5.7 ubuntu 18.04中进行了测试。

set global sql_mode="NO_ENGINE_SUBSTITUTION";

在全局运行这个查询之前,我在/etc/mysql/conf中添加了一个cnf文件。d目录。cnf文件的名称是mysql.cnf和代码

[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

然后重启mysql

sudo service mysql restart

希望这能帮助到一些人。

SET sql_mode = 'NO_ZERO_DATE';
UPDATE `news` SET `d_stop`='2038-01-01 00:00:00' WHERE `d_stop`='0000-00-00 00:00:00'

您可以将创建的字段的类型从datetime更改为varchar(255),然后您可以将(更新)所有值为“0000-00-00 00:00:00”的记录设置为NULL。

现在,您可以无错误地执行查询。 完成后,您可以更改创建为datetime的字段类型。

下面是我的解决方案PhpMyAdmin / Fedora 29 / MySQL 8.0(以)为例:

设置sql_mode = '东西';不工作,命令调用成功,但什么都没有改变。

set GLOBAL sql_mode='SOMETHING';更改全局配置永久更改。

set SESSION sql_mode='SOMETHING';session变量只影响当前客户端。

https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html

所以我这样做:

显示类似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中,如果您拥有服务器的控制权,您可以直接在Plus > Variables > sql_mode中更改sql_mode(以及所有其他参数)

使sql模式不严格

如果使用laravel,进入config->数据库,进入mysql设置,使严格模式为假