mysql met à jour plusieurs colonnes avec la même chose maintenant ()

87

J'ai besoin de mettre à jour 2 colonnes datetime, et j'ai besoin qu'elles soient exactement les mêmes, en utilisant la version 4.1.20 de mysql. J'utilise cette requête:

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

C'est sûr ou il est possible que les colonnes soient mises à jour avec une heure différente, en raison des 2 appels visibles à now()?
Je ne pense pas que cela puisse être mis à jour avec des valeurs différentes (je pense qu'en interne, mysql n'appelle now()qu'une seule fois par ligne ou quelque chose de similaire), mais je ne suis pas un expert, qu'en pensez-vous?

Mise à jour: la deuxième question a été extraite ici .

Radu Maris
la source
1
Je vous suggère de supprimer votre deuxième question d'ici, et de la republier éventuellement dans un article séparé.
Cœur

Réponses:

144

Trouvé une solution:

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

J'ai trouvé cela dans MySQL Docs et après quelques tests, cela fonctionne:

l'instruction suivante définit col2 sur la valeur col1 actuelle (mise à jour), et non sur la valeur col1 d'origine. Le résultat est que col1 et col2 ont la même valeur. Ce comportement diffère du SQL standard.

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

Radu Maris
la source
Est-il possible que cela ne fonctionne pas? Dans une procédure ou en utilisant une jointure avec des tables temporaires?
Soheil Rahsaz le
7

Mysql n'est pas très intelligent. Lorsque vous souhaitez utiliser le même horodatage dans plusieurs requêtes de mise à jour ou d'insertion, vous devez déclarer une variable.

Lorsque vous utilisez la now()fonction, le système appellera l'horodatage actuel chaque fois que vous l'appelez dans une autre requête.

Olivier
la source
5

MySQL évalue now () une fois par instruction lorsque celle-ci commence son exécution. Il est donc sûr d'avoir plusieurs appels now () visibles par instruction.

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
la source
1

Vous pouvez stocker la valeur d'un now () dans une variable avant d'exécuter la requête de mise à jour, puis utiliser cette variable pour mettre à jour les champs last_updateet last_monitor.

Cela garantira que now () n'est exécuté qu'une seule fois et que la même valeur est mise à jour sur les deux colonnes dont vous avez besoin.

Sachin Shanbhag
la source
1

Vous pouvez mettre le code suivant sur la valeur par défaut de la colonne d'horodatage:, CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPdonc de mise à jour, les deux colonnes prennent la même valeur.

Danny
la source
1
AFAIK "on update" a une limite d'une colonne par table, donc ne peut pas le définir sur les deux colonnes.
Radu Maris
0

Si vous avez vraiment besoin d'être sûr que cela now()a la même valeur, vous pouvez exécuter deux requêtes (qui répondront également à votre deuxième question, dans ce cas, vous le demandez update last_monitor = to last_updatemais vous n'avez last_updatepas encore été mis à jour)

vous pouvez faire quelque chose comme:

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

de toute façon je pense que mysql est assez intelligent pour ne demander now()qu'une seule fois par requête.

sathia
la source
Et les deux mises à jour? devinez-vous aussi que mysql est assez intelligent pour les combiner en une seule instruction? parce que ce ne sera pas le cas.
Rafael Herscovici
0

Il y a 2 façons de procéder;

Tout d'abord , je vous conseillerais de déclarer now () comme une variable avant de l'injecter dans l'instruction sql. Disons;

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

Logiquement, si vous voulez une entrée différente pour last_monitor, vous ajouterez une autre variable comme;

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

De cette façon, vous pouvez utiliser les variables autant de fois que vous le pouvez, non seulement dans les instructions mysql mais aussi dans le langage de script côté serveur (comme PHP) que vous utilisez dans votre projet. N'oubliez pas que ces mêmes variables peuvent être insérées en tant qu'entrées dans un formulaire sur le front-end de l'application. Cela rend le projet dynamique et non statique.

Deuxièmement, si now () indique l'heure de la mise à jour, alors en utilisant mysql, vous pouvez décaler la propriété de la ligne comme un horodatage. Chaque fois qu'une ligne est insérée ou mise à jour, l'heure est également mise à jour.

Wahinya Brian
la source
Bienvenue à SO. Bien que ce soit une solution au problème, cela ne répond pas vraiment à la question qui est "Y a-t-il un problème avec la fonction NOW () intégrée à mysql?". Vous suggérez également d'utiliser une langue externe sur laquelle l'affiche peut n'avoir aucun contrôle. Votre deuxième suggestion dont je ne suis pas sûr (mon souvenir de mysql n'est pas si détaillé), mais la soutenir avec des liens vers des documents / exemples donnerait beaucoup plus de crédibilité.
Martin
Dans ma deuxième suggestion, si now () doit être utilisé comme horodatage chaque fois qu'une mise à jour a lieu, le lien suivant peut aider; alvinalexander.com/mysql/... Dans ma 1ère suggestion, chaque colonne d'une table mysql est indépendante. Par conséquent, la saisie des données (comme l'utilisation d'une variable dans la question ci-dessus) se fait indépendamment. Cependant, vous pouvez comparer et contraster les données dans différentes colonnes à l'aide d'opérateurs tels que>, <, =,! =,! <. Cela signifie simplement que vous ne pouvez pas saisir de données dans les cols comme ceci; mysql> table de mise à jour définie last_update = last_monitor = now () où id = 1;
Wahinya Brian