Mysql обновляет несколько столбцов с такими же моментами()

Мне нужно обновить 2 столбца datetime, и мне нужно, чтобы они были точно такими же, используя MySQL версии 4.1.20. Я использую этот запрос:

mysql> update table set last_update=now(), last_monitor=now() where id=1;

Это безопасно или есть вероятность, что столбцы обновляются с различным временем из-за 2 видимых вызовов now()?
Я не думаю, что он может быть обновлен с другими значениями (я думаю, что внутренне mysql вызывает now() только один раз в строку или что-то подобное), но я не эксперт, как вы думаете?

Обновление: Второй вопрос был извлечен здесь.

Ответ 1

Нашел решение:

mysql> UPDATE table SET last_update=now(), last_monitor=last_update WHERE id=1;

Я нашел это в MySQL Docs и после нескольких тестов это работает:

следующий оператор устанавливает для col2 текущее (обновленное) значение col1, а не исходное значение col1. В результате col1 и col2 имеют одинаковое значение. Это поведение отличается от стандартного SQL.

ОБНОВЛЕНИЕ t1 SET col1 = col1 + 1, col2 = col1;

Ответ 2

Mysql не очень умный. Если вы хотите использовать одну и ту же метку времени в нескольких обновлениях или вставить запросы, вам нужно объявить переменную.

Когда вы используете функцию now(), система будет вызывать текущую временную метку каждый раз, когда вы вызываете ее в другом запросе.

Ответ 3

Вы можете сохранить значение now() в переменной перед запуском запроса на обновление, а затем использовать эту переменную для обновления полей last_update и last_monitor.

Это гарантирует, что now() будет выполняться только один раз, а одно и то же значение обновляется по обоим столбцам, которые вам нужны.

Ответ 4

Вы можете поместить следующий код в значение по умолчанию столбца метки времени: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, поэтому обновление двух столбцов принимает одинаковое значение.

Ответ 5

MySQL вычисляет now() один раз для каждого оператора, когда оператор начинает выполнение. Поэтому безопасно иметь несколько видимых вызовов now() для каждого оператора.

select now(); select now(), sleep(10), now(); select now();
+---------------------+
| now()               |
+---------------------+
| 2018-11-05 16:54:00 |
+---------------------+
1 row in set (0.00 sec)

+---------------------+-----------+---------------------+
| now()               | sleep(10) | now()               |
+---------------------+-----------+---------------------+
| 2018-11-05 16:54:00 |         0 | 2018-11-05 16:54:00 |
+---------------------+-----------+---------------------+
1 row in set (10.00 sec)

+---------------------+
| now()               |
+---------------------+
| 2018-11-05 16:54:10 |
+---------------------+
1 row in set (0.00 sec)

Ответ 6

Если вам действительно нужно быть уверенным, что now() имеет то же значение, вы можете запустить два запроса (которые будут отвечать на ваш второй вопрос тоже, в этом случае вы запрашиваете update last_monitor = to last_update, но last_update не имеет обновлено)

вы можете сделать что-то вроде:

mysql> update table set last_update=now() where id=1;
mysql> update table set last_monitor = last_update where id=1;

В любом случае, я думаю, что mysql достаточно умен, чтобы запрашивать now() только один раз за запрос.

Ответ 7

Есть 2 пути к этому;

Во-первых, я бы посоветовал вам объявить now() как переменную, прежде чем вставлять ее в оператор sql. Давайте скажем;

var x = now();
mysql> UPDATE table SET last_update=$x, last_monitor=$x WHERE id=1;

Логически, если вы хотите другой ввод для last_monitor, вы добавите еще одну переменную наподобие;

var y = time();
mysql> UPDATE table SET last_update=$x, last_monitor=$y WHERE id=1;

Таким образом, вы можете использовать переменные столько раз, сколько сможете, не только в выражениях mysql, но и на языке сценариев на стороне сервера (например, PHP), который вы используете в своем проекте. Помните, что эти же переменные могут быть вставлены в виде входных данных в форме на внешней стороне приложения. Это делает проект динамичным, а не статичным.

Во-вторых, если now() указывает время обновления, то с помощью mysql вы можете декальзировать свойство строки как метку времени. Каждый раз, когда строка вставляется или обновляется время тоже обновляется.