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

87

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

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

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

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

Раду Марис
источник
1
Я предлагаю вам удалить здесь свой второй вопрос и в конечном итоге опубликовать его в отдельном посте.
Cœur

Ответы:

144

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

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;

Раду Марис
источник
Есть ли способ, чтобы это не сработало? В процедуре или с помощью объединения с временными таблицами?
Сохейл Рахсаз,
7

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

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

Оливье
источник
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)
Рич Эндрюс
источник
1

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

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

Сачин Шанбхаг
источник
1

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

Дэнни
источник
1
AFAIK «при обновлении» имеет ограничение в один столбец на таблицу, поэтому нельзя установить его для обоих столбцов.
Radu Maris
0

Если вам действительно нужно быть уверенным, что у 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()только один раз за запрос.

сатия
источник
Как насчет двух обновлений? Вы также думаете, что mysql достаточно умен, чтобы объединить их в один оператор? потому что это не так.
Rafael Herscovici
0

Для этого есть 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 вы можете преобразовать свойство строки в метку времени. Каждый раз, когда строка вставляется или обновляется, также обновляется время.

Вахинья Брайан
источник
Добро пожаловать в SO. Хотя это решение проблемы, на самом деле оно не отвечает на вопрос «Есть ли проблема с использованием встроенной функции mysql NOW ()?». Также вы предлагаете использовать внешний язык, который автор не может контролировать. Ваше второе предложение, в котором я не уверен (мое воспоминание о mysql не так подробно), но его поддержка ссылками на некоторые документы / примеры дала бы гораздо больше доверия.
Мартин
Во втором предложении, если now () будет использоваться в качестве отметки времени при каждом обновлении, следующая ссылка может помочь; alvinalexander.com/mysql/… В моем первом предложении каждый столбец в таблице mysql независим. Следовательно, ввод данных (например, использование одной переменной в вопросе выше) выполняется независимо. Однако вы можете сравнивать и сопоставлять данные в разных столбцах, используя такие операторы, как>, <, =,! = ,! <. Это просто означает, что вы не можете вводить данные в такие столбцы; mysql> набор обновлений таблицы last_update = last_monitor = now (), где id = 1;
Wahinya Brian