MySQL 将数据 VARCHAR 转换为 DATETIME

MySQL Convert data VARCHAR to DATETIME

table users 设计得很糟糕。 created_atupdated_at 记录设置为VARCHAR 类型,值以20.10.2017 8:10 格式长期放置在其中。

需要将字段转换为 MySQL 中的 DATETIME 类型,保存之前输入的值。

STR_TO_DATETIME 函数不是 suitable 因为它改变了输出格式,而不是 VARCHAR 数据类型本身到 DATETIME 数据类型 table。

ALTER TABLE users MODIFY created_at DATETIME

不起作用

错误信息:

SQL Error [1292] [22001]: Data truncation: Incorrect datetime value: '06.01.2020 8:10' for column 'created_at' at row 1

解决此问题的最简单方法是创建新的 created_atupdated_at DATETIME 列,为它们分配已解析的日期值,然后删除旧列并重命名新的。例如:

ALTER TABLE users ADD new_created_at DATETIME
UPDATE users SET new_created_at = STR_TO_DATE(created_at, '%d.%m.%Y %l:%i')
ALTER TABLE users DROP created_at, CHANGE new_created_at created_at DATETIME

Demo on dbfiddle

正如@BillKarwin 指出的那样,您应该检查 new_created_at 是否包含有效值 删除 created_at 列之前,以防某些日期不匹配格式。您可以使用

检查这些情况
SELECT *
FROM users
WHERE new_created_at IS NULL

正如@Barmar 指出的那样,最好先在 table.

的备份副本中尝试此操作

当您将列从 VARCHAR 更改为 DATETIME 时,您无法指定字符串的自定义解析,它必须采用 MySQL 的默认格式.

因此您需要分多个步骤执行此操作:

  1. 添加 DATETIME 列。
  2. 通过STR_TO_DATE()
  3. 解析VARCHAR列来填充新列
  4. 删除旧列并重命名新列。
ALTER TABLE users ADD created_at_dt DATETIME, updated_at_dt DATETIME;
UPDATE users
SET created_at_dt = STR_TO_DATE(created_at, '%d.%m.%Y %h:%i'),
    updated_at_dt = STR_TO_DATE(updated_at, '%d.%m.%Y %h:%i');
ALTER TABLE users 
    DROP created_at, DROP updated_at, 
    RENAME COLUMN created_at_dt TO created_at, RENAME COLUMN updated_at_dt TO updated_at;

您的日期格式错误,将其转换为正确的 mysql 时间,然后更改 table

select version();
| version() |
| :-------- |
| 8.0.19    |
CREATE TABLE users
    (`created_at` varchar(20))
;

INSERT INTO users
    (`created_at`)
VALUES
    ("06.01.2020 8:10"),
    ("07.01.2020 8:10"),
    ("08.01.2020 8:10"),
    ("09.01.2020 8:10")
✓

✓
SELECT STR_TO_DATE(created_at, "%d.%m.%Y %k:%i") FROM users;
| STR_TO_DATE(created_at, "%d.%m.%Y %k:%i") |
| :---------------------------------------- |
| 2020-01-06 08:10:00                       |
| 2020-01-07 08:10:00                       |
| 2020-01-08 08:10:00                       |
| 2020-01-09 08:10:00                       |
UPDATE users SET created_at = STR_TO_DATE(created_at, "%d.%m.%Y %k:%i");
SELECT * FROM users;
| created_at          |
| :------------------ |
| 2020-01-06 08:10:00 |
| 2020-01-07 08:10:00 |
| 2020-01-08 08:10:00 |
| 2020-01-09 08:10:00 |
ALTER TABLE users MODIFY created_at DATETIME
SELECT * FROM users;
| created_at          |
| :------------------ |
| 2020-01-06 08:10:00 |
| 2020-01-07 08:10:00 |
| 2020-01-08 08:10:00 |
| 2020-01-09 08:10:00 |

db<>fiddle here