MySQL Конвертировать данные VARCHAR в DATETIME - PullRequest
0 голосов
/ 16 января 2020

Стол users был плохо спроектирован. Записи created_at и updated_at были установлены с типом VARCHAR, и значения долгое время помещались в них в формате, подобном 20.10.2017 8:10.

Необходимо преобразовать поля в тип DATETIME в MySQL, сохранив введенные ранее значения.

Функция STR_TO_DATETIME не подходит, поскольку она меняет формат вывода, но не сам тип данных VARCHAR для типа данных DATETIME в таблице.

ALTER TABLE users MODIFY created_at DATETIME

не работает

Сообщение об ошибке:

SQL Ошибка [1292] [22001]: усечение данных: неверное значение даты-времени: '06 .01 .2020 8:10 для столбца созданного в строке 1

Ответы [ 3 ]

1 голос
/ 16 января 2020

Когда вы изменяете столбец с VARCHAR на DATETIME, вы не можете указать пользовательский анализ строки, он должен быть в формате MySQL по умолчанию.

Так вам нужно сделать это в несколько шагов:

  1. Добавить столбец DATETIME.
  2. Заполнить новый столбец, проанализировав столбец VARCHAR с помощью STR_TO_DATE()
  3. Удалите старый столбец и переименуйте новый столбец.
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;
1 голос
/ 16 января 2020

Самый простой способ обойти это - создать новые столбцы created_at и updated_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

Демонстрация на dbfiddle

Как указывает @BillKarwin, вы должны проверить, что new_created_at содержит действительные значения до удаление столбца created_at на случай, если некоторые даты не соответствуют формату. Вы можете проверить эти случаи, используя

SELECT *
FROM users
WHERE new_created_at IS NULL

И, как указывает @Barmar, лучше сначала попробовать это в резервной копии таблицы.

0 голосов
/ 16 января 2020

Ваша дата имеет ложный формат. Преобразуйте ее в правильное mysql время, а затем измените таблицу.

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 <> скрипка здесь

...