mysql aggiorna più colonne con lo stesso now ()


88

Devo aggiornare 2 colonne datetime e ho bisogno che siano esattamente le stesse, utilizzando mysql versione 4.1.20. Sto usando questa query:

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

È sicuro o c'è la possibilità che le colonne vengano aggiornate con tempi diversi, a causa delle 2 chiamate visibili a now()?
Non penso che possa essere aggiornato con valori diversi (penso che internamente mysql chiami now()solo una volta per riga o qualcosa di simile), ma non sono un esperto, cosa ne pensi?

Aggiornamento: la seconda domanda è stata estratta qui .


1
Ti suggerisco di rimuovere la tua seconda domanda da qui e alla fine ripubblicarla in un post separato.
Cœur

Risposte:


145

Trovato una soluzione:

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

Ho trovato questo in MySQL Docs e dopo alcuni test funziona:

la seguente istruzione imposta col2 al valore col1 corrente (aggiornato), non al valore col1 originale. Il risultato è che col1 e col2 hanno lo stesso valore. Questo comportamento è diverso dallo standard SQL.

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


C'è un modo in cui questo non funzionerebbe? In una procedura o utilizzando join con tabelle temporanee?
Soheil Rahsaz

7

Mysql non è molto intelligente. Quando si desidera utilizzare lo stesso timestamp in più query di aggiornamento o inserimento, è necessario dichiarare una variabile.

Quando si utilizza la now()funzione, il sistema chiamerà il timestamp corrente ogni volta che lo si chiama in un'altra query.


5

MySQL valuta now () una volta per istruzione quando l'istruzione inizia l'esecuzione. Quindi è sicuro avere più chiamate visibili now () per istruzione.

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

È possibile memorizzare il valore di now () in una variabile prima di eseguire la query di aggiornamento e quindi utilizzare quella variabile per aggiornare sia i campi last_updatechelast_monitor .

Ciò garantirà che now () venga eseguito solo una volta e che lo stesso valore venga aggiornato su entrambe le colonne necessarie.


1

È possibile inserire il seguente codice nel valore predefinito della colonna timestamp:, CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPquindi all'aggiornamento le due colonne assumono lo stesso valore.


1
Per quanto ne so "in aggiornamento" ha un limite di una colonna per tabella, quindi non è possibile impostarlo su entrambe le colonne.
Radu Maris

0

Se hai davvero bisogno di essere sicuro che now()abbia lo stesso valore puoi eseguire due query (che risponderanno anche alla tua seconda domanda, in quel caso stai chiedendo update last_monitor = to last_updatemalast_update non è stato ancora aggiornato)

potresti fare qualcosa come:

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

comunque penso che mysql sia abbastanza intelligente da chiedere now()solo una volta per query.


E i due aggiornamenti? indovinate anche che mysql è abbastanza intelligente da combinarli in un'unica istruzione? perché non lo farà.
Rafael Herscovici

0

Ci sono 2 modi per farlo;

Innanzitutto , ti consiglio di dichiarare now () come variabile prima di inserirla nell'istruzione sql. Diciamo;

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

Logicamente se vuoi un input diverso per last_monitor, aggiungerai un'altra variabile come;

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

In questo modo puoi usare le variabili tutte le volte che puoi, non solo nelle istruzioni mysql ma anche nel linguaggio di scripting lato server (come PHP) che stai usando nel tuo progetto. Ricorda che queste stesse variabili possono essere inserite come input in un modulo sul front-end dell'applicazione. Ciò rende il progetto dinamico e non statico.

In secondo luogo se now () indica l'ora dell'aggiornamento quindi utilizzando mysql è possibile decalre la proprietà della riga come timestamp. Ogni volta che viene inserita una riga o viene aggiornata anche l'ora.


Benvenuto in SO. Sebbene questa sia una soluzione al problema, in realtà non risponde alla domanda "C'è un problema nell'utilizzo della funzione NOW () incorporata di mysql?". Inoltre suggerisci di utilizzare una lingua esterna su cui il poster potrebbe non avere alcun controllo. Il tuo secondo suggerimento di cui non sono sicuro (il mio ricordo di mysql non è così dettagliato) ma supportarlo con collegamenti ad alcuni documenti / esempi darebbe molta più credibilità.
Martin

Nel mio secondo suggerimento, se now () deve essere usato come un timestamp ogni volta che si verifica un aggiornamento, il seguente link può aiutare; alvinalexander.com/mysql/… Nel mio primo suggerimento, ogni colonna in una tabella mysql è indipendente. Quindi l'inserimento dei dati (come l'utilizzo di una variabile nella domanda precedente) viene eseguito in modo indipendente. Tuttavia è possibile confrontare e confrontare i dati in colonne diverse utilizzando operatori come>, <, =,! = ,! <. Questo significa semplicemente che non puoi inserire dati nelle colonne in questo modo; mysql> update table set last_update = last_monitor = now () dove id = 1;
Wahinya Brian
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.