mysql aktualisiere jetzt mehrere Spalten mit derselben ()

87

Ich muss 2 Datetime-Spalten aktualisieren und sie müssen mit MySQL Version 4.1.20 genau gleich sein. Ich benutze diese Abfrage:

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

Es ist sicher oder es besteht die Möglichkeit, dass die Spalten aufgrund der 2 sichtbaren Aufrufe von zu unterschiedlichen Zeiten aktualisiert werden now() ? .
Ich denke nicht, dass es mit unterschiedlichen Werten aktualisiert werden kann (ich denke, intern ruft MySQL now()nur einmal pro Zeile oder ähnliches auf), aber ich bin kein Experte, was denkst du?

Update: Die zweite Frage wurde hier extrahiert .

Radu Maris
quelle
1
Ich schlage vor, dass Sie Ihre zweite Frage von hier entfernen und sie schließlich in einem separaten Beitrag erneut veröffentlichen.
Cœur

Antworten:

144

Eine Lösung gefunden:

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

Ich habe dies in MySQL Docs gefunden und nach ein paar Tests funktioniert es:

Die folgende Anweisung setzt col2 auf den aktuellen (aktualisierten) col1-Wert, nicht auf den ursprünglichen col1-Wert. Das Ergebnis ist, dass col1 und col2 den gleichen Wert haben. Dieses Verhalten unterscheidet sich von Standard-SQL.

UPDATE t1 SET col1 = col1 + 1, col2 = col1;

Radu Maris
quelle
7

MySQL ist nicht sehr klug. Wenn Sie denselben Zeitstempel in mehreren Aktualisierungs- oder Einfügeabfragen verwenden möchten, müssen Sie eine Variable deklarieren.

Wenn Sie die now()Funktion verwenden, ruft das System den aktuellen Zeitstempel jedes Mal auf, wenn Sie ihn in einer anderen Abfrage aufrufen.

Olivier
quelle
4

MySQL wertet now () einmal pro Anweisung aus, wenn die Anweisung mit der Ausführung beginnt. Es ist also sicher, mehrere sichtbare now () -Aufrufe pro Anweisung zu haben.

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)
Rich Andrews
quelle
1

Sie können den Wert von now () in einer Variablen speichern, bevor Sie die Aktualisierungsabfrage ausführen, und diese Variable dann verwenden, um sowohl die Felder last_updateals auch zu aktualisierenlast_monitor .

Dadurch wird sichergestellt, dass now () nur einmal ausgeführt wird und der gleiche Wert für beide benötigten Spalten aktualisiert wird.

Sachin Shanbhag
quelle
1

Sie können den folgenden Code auf den Standardwert der Zeitstempelspalte setzen: Beim CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPAktualisieren nehmen die beiden Spalten denselben Wert an.

Danny
quelle
1
AFAIK "on update" ist auf eine Spalte pro Tabelle begrenzt und kann daher nicht auf beide Spalten festgelegt werden.
Radu Maris
0

Wenn Sie wirklich sicher sein müssen, dass now()derselbe Wert denselben Wert hat, können Sie zwei Abfragen ausführen (die auch Ihre zweite Frage beantworten. In diesem Fall werden Sie gefragt, update last_monitor = to last_updateaber last_updatenoch nicht aktualisiert).

Sie könnten so etwas tun wie:

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

Trotzdem denke ich, dass MySQL klug genug ist, now()nur einmal pro Abfrage zu fragen .

Sathia
quelle
Wie wäre es mit den beiden Updates? Vermutest du auch, dass MySQL klug genug ist, um sie zu einer Aussage zu kombinieren? weil es nicht wird.
Rafael Herscovici
0

Hierfür gibt es zwei Möglichkeiten.

Zunächst würde ich Ihnen raten, now () als Variable zu deklarieren, bevor Sie sie in die SQL-Anweisung einfügen. Sagen wir;

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

Wenn Sie eine andere Eingabe für last_monitor wünschen, fügen Sie logischerweise eine weitere Variable hinzu, z.

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

Auf diese Weise können Sie die Variablen so oft wie möglich verwenden, nicht nur in MySQL-Anweisungen, sondern auch in der serverseitigen Skriptsprache (wie PHP), die Sie in Ihrem Projekt verwenden. Denken Sie daran, dass dieselben Variablen als Eingaben in ein Formular im Front-End der Anwendung eingefügt werden können. Das macht das Projekt dynamisch und nicht statisch.

Zweitens, wenn now () den Zeitpunkt der Aktualisierung angibt, können Sie mit mysql die Eigenschaft der Zeile als Zeitstempel dekalieren. Jedes Mal, wenn eine Zeile eingefügt oder aktualisiert wird, wird auch die Zeit aktualisiert.

Wahinya Brian
quelle
Willkommen bei SO. Obwohl dies eine Lösung für das Problem ist, beantwortet es nicht wirklich die Frage "Gibt es ein Problem bei der Verwendung der in mysql integrierten NOW () -Funktion?". Sie schlagen außerdem vor, eine externe Sprache zu verwenden, über die das Poster möglicherweise keine Kontrolle hat. Ihr zweiter Vorschlag, bei dem ich mir nicht sicher bin (meine Erinnerung an MySQL ist nicht so detailliert), aber die Unterstützung mit Links zu einigen Dokumenten / Beispielen würde weitaus mehr Glaubwürdigkeit verleihen.
Martin
In meinem zweiten Vorschlag kann der folgende Link hilfreich sein, wenn now () bei jeder Aktualisierung als Zeitstempel verwendet werden soll. alvinalexander.com/mysql/… In meinem ersten Vorschlag ist jede Spalte in einer MySQL-Tabelle unabhängig. Daher erfolgt die Dateneingabe (wie bei Verwendung einer Variablen in der obigen Frage) unabhängig. Sie können jedoch Daten in verschiedenen Spalten mit Operatoren wie>, <, = ,! =,! <Vergleichen und kontrastieren. Dies bedeutet einfach, dass Sie keine Daten wie diese in die Spalten eingeben können. mysql> update table set last_update = last_monitor = now () wobei id = 1;
Wahinya Brian