Столбец с предупреждением о выходе за пределы допустимого диапазона для условного обновления

У меня есть единственный запрос для обновления таблицы, и некоторые поля должны обновляться при определенных условиях, давайте представим этот случай:

У меня есть таблица с именем mytable, в ней есть поле DATETIME с именем установлен, это поле может быть пустым и по умолчанию имеет значение NULL, а иногда некоторые значения - «0000-00-00 00:00:00».

Когда я получаю данные от любого датчика (пример: идентификатор датчика 12457), я обновляю его значения следующим образом:

UPDATE mytable SET
temperature=35,
pressure=122,
installed=NOW(),
status=1
WHERE id=12457

если я получаю новые данные от того же датчика, я снова сохраняю его значения, но избегаю изменения установленного значения таким образом:

UPDATE mytable SET
temperature=35,
pressure=122,
installed=IF(installed IS NULL,NOW(),installed),
status=1
WHERE id=12457

Он работает так, как ожидалось, если установлено значение null, он сохраняет текущее время, если нет, он сохраняет предыдущую дату, но я получаю это предупреждение, когда дата равна '0000-00-00 00:00:00':

Предупреждение: значение вне допустимого диапазона для столбца "установлен" в строке 1

Как предложил Д-Ши, я попытался использовать COALESCE следующим образом, но получил то же предупреждение:

installed=COALESCE(installed,NOW())

Я подумал, что это из-за предыдущей даты, поэтому я намеренно попытался воспроизвести ошибку, сделав следующее:

UPDATE mytable SET
installed=installed,
WHERE id=12457

Но я не получил предупреждения.

Система работает правильно, но мне немного любопытно, почему я получаю это предупреждение, используя только функцию IF (или COALESCE)?


Отвечая на Мадур Бхайя:

SHOW CREATE TABLE mytable

CREATE TABLE `mytable` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `temperature` INT(11) NOT NULL DEFAULT '0',
    `pressure` INT(11) NOT NULL DEFAULT '0',
    `installed` DATETIME NULL DEFAULT NULL,
    `status` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)

Пример данных:

INSERT INTO `mytable` VALUES (12457, 35, 122, '2018-12-12 12:53:49', 1);
INSERT INTO `mytable` VALUES (12458, 40, 119, '0000-00-00 00:00:00', 1);
INSERT INTO `mytable` VALUES (12459, 34, 122, null, 1);
INSERT INTO `mytable` VALUES (12460, 36, 122, '2018-12-12 12:57:01', 1);

Версия MySQL: 5.7.23

поделитесь результатом SHOW CREATE TABLE mytable. Также поделитесь деталями некоторых образцов данных. Кроме того, какая у вас версия сервера MySQL?

Madhur Bhaiya 12.12.2018 14:28

P.Salmon теперь вы говорите это, у меня это предупреждение только на таких датах, как 0000-00-00 00:00:00, это может быть причиной?

stramin 12.12.2018 14:40

Почему у вас есть значения даты 0000-00-00?

Madhur Bhaiya 12.12.2018 14:46

Я действительно не знаю, датчики сделаны с Raspberry PI, читающим строку CSV, я думаю, что иногда они не могут правильно прочитать дату.

stramin 12.12.2018 14:48

Попробуйте COALESCE(CAST(installed AS DATETIME), CAST(NOW() AS DATETIME)). Просто из любопытства...

Alexey 12.12.2018 14:59

Алексей, приятно, никаких предупреждений при использовании CAST в установленном: installed=COALESCE(CAST(installed AS DATETIME), NOW()), зачем мне CAST, если это уже DATETIME? и почему я не делаю этого предупреждения: installed=installed?

stramin 12.12.2018 15:15

@stramin, я думаю, это потому, что NOW () возвращает строку, а значение поля installed имеет тип DATETIME. И почему-то mysql не нравится, что в одном и том же IF или COALESCE у вас есть значения двух разных типов.

Alexey 12.12.2018 15:29

Хм ... нет, мой предыдущий комментарий неверен. Вы не транслируете NOW() и в любом случае не получаете предупреждения.

Alexey 12.12.2018 15:32

Это может быть ошибка MySQL или что-то в этом роде? : o

stramin 12.12.2018 21:43
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
9
41
1

Ответы 1

У вас есть 0000-00-00 00:00:00 как значения также в столбце installed. Вам также необходимо обрабатывать их, помимо значений null. Также перед запуском запроса вам необходимо установить sql_mode на '', так как это удалит более строгий режим SQL NO_ZERO_DATE.

SET SESSION sql_mode = '';

UPDATE mytable 
SET
  temperature = 35,
  pressure = 122,
  installed = IF(installed IS NULL OR installed = '0000-00-00 00:00:00',
                 NOW(),
                 installed),
  status=1
WHERE id=12457

Спасибо, но теперь я получаю новое предупреждение: Warning: Incorrect datetime value: '0000-00-00 00:00:00' for column 'installed' at row 1, теперь меня это еще больше интересует ... И мне все еще интересно, почему это происходит только с условными функциями?

stramin 12.12.2018 14:51

Другие вопросы по теме