mysql zaktualizuj wiele kolumn za pomocą tego samego now ()

87

Muszę zaktualizować 2 kolumny z datą i godziną i chcę, aby były dokładnie takie same, używając mysql w wersji 4.1.20. Używam tego zapytania:

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

Jest to bezpieczne lub jest szansa, że ​​kolumny są aktualizowane z różnym czasem, z powodu 2 widocznych wywołań now()?
Nie sądzę, że można to aktualizować różnymi wartościami (myślę, że wewnętrznie wywołania mysql now()tylko raz na wiersz lub coś podobnego), ale nie jestem ekspertem, co o tym sądzisz?

Aktualizacja: Tutaj wyodrębniono drugie pytanie .

Radu Maris
źródło
1
Sugeruję, abyś usunął stąd swoje drugie pytanie i ostatecznie opublikował je ponownie w osobnym poście.
Cœur

Odpowiedzi:

144

Znalazłem rozwiązanie:

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

Znalazłem to w MySQL Docs i po kilku testach działa:

poniższa instrukcja ustawia col2 na bieżącą (zaktualizowaną) wartość col1, a nie oryginalną wartość col1. W rezultacie col1 i col2 mają tę samą wartość. To zachowanie różni się od standardowego SQL.

UPDATE t1 SET kol1 = kol1 + 1, kol2 = kol1;

Radu Maris
źródło
Czy jest jakiś sposób, żeby to nie zadziałało? W procedurze lub przy użyciu łączenia z tabelami tymczasowymi?
Soheil Rahsaz
7

MySQL nie jest zbyt sprytny. Jeśli chcesz użyć tego samego znacznika czasu w wielu zapytaniach o aktualizację lub wstawianie, musisz zadeklarować zmienną.

Podczas korzystania z tej now()funkcji system wywoła bieżący znacznik czasu za każdym razem, gdy wywołasz ją w innym zapytaniu.

Olivier
źródło
5

MySQL ocenia now () raz na instrukcję, gdy instrukcja rozpoczyna wykonywanie. Dlatego można bezpiecznie mieć wiele widocznych wywołań funkcji now () na instrukcję.

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)
Bogaty Andrews
źródło
1

Możesz zapisać wartość now () w zmiennej przed uruchomieniem zapytania aktualizującego, a następnie użyć tej zmiennej do zaktualizowania zarówno pól, jak last_updatei last_monitor.

Dzięki temu funkcja now () zostanie wykonana tylko raz, a ta sama wartość zostanie zaktualizowana w obu potrzebnych kolumnach.

Sachin Shanbhag
źródło
1

Możesz umieścić następujący kod na domyślnej wartości kolumny timestamp: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPtak więc w aktualizacji dwie kolumny przyjmują tę samą wartość.

Danny
źródło
1
AFAIK „przy aktualizacji” ma limit jednej kolumny na tabelę, więc nie można ustawić go na obie kolumny.
Radu Maris
0

Jeśli naprawdę chcesz mieć pewność, że now()ma tę samą wartość, możesz uruchomić dwa zapytania (to również odpowie na twoje drugie pytanie, w takim przypadku o to prosisz, update last_monitor = to last_updateale last_updatenie zostało jeszcze zaktualizowane)

możesz zrobić coś takiego:

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

w każdym razie myślę, że mysql jest na tyle sprytny, że prosi now()tylko raz na zapytanie.

satia
źródło
A co z dwiema aktualizacjami? czy sądzisz, że mysql jest wystarczająco inteligentny, aby połączyć je w jedną instrukcję? ponieważ nie będzie.
Rafael Herscovici
0

Są na to 2 sposoby;

Najpierw radziłbym zadeklarować now () jako zmienną przed wstrzyknięciem jej do instrukcji sql. Powiedzmy;

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

Logicznie rzecz biorąc, jeśli chcesz mieć inne dane wejściowe dla last_monitor, dodasz kolejną zmienną, taką jak;

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

W ten sposób możesz używać zmiennych tyle razy, ile możesz, nie tylko w instrukcjach mysql, ale także w języku skryptowym po stronie serwera (takim jak PHP), którego używasz w swoim projekcie. Pamiętaj, że te same zmienne mogą być wstawiane jako dane wejściowe w formularzu na interfejsie aplikacji. To sprawia, że ​​projekt jest dynamiczny, a nie statyczny.

Po drugie, jeśli teraz () wskazuje czas aktualizacji, to używając mysql możesz zdekalować właściwość wiersza jako znacznik czasu. Za każdym razem, gdy wiersz jest wstawiany lub aktualizowany, aktualizowany jest również czas.

Wahinya Brian
źródło
Witamy w SO. Chociaż jest to rozwiązanie problemu, tak naprawdę nie odpowiada na pytanie „Czy jest jakiś problem z używaniem funkcji NOW () wbudowanej mysql?”. Sugerujesz również użycie języka zewnętrznego, nad którym plakat może nie mieć kontroli. Twoja druga sugestia, której nie jestem pewien (moje wspomnienie mysql nie jest tak szczegółowe), ale wsparcie jej linkami do niektórych dokumentów / przykładów dałoby znacznie większą wiarygodność.
Martin
Według mojej drugiej sugestii, jeśli now () ma być używany jako znacznik czasu za każdym razem, gdy ma miejsce jakakolwiek aktualizacja, poniższe łącze może pomóc; alvinalexander.com/mysql/… Według mojej pierwszej sugestii, każda kolumna w tabeli mysql jest niezależna. Dlatego wprowadzanie danych (podobnie jak użycie jednej zmiennej w powyższym pytaniu) odbywa się niezależnie. Możesz jednak porównywać i kontrastować dane w różnych kolumnach za pomocą operatorów, takich jak>, <, =,! = ,! <. Oznacza to po prostu, że nie możesz wprowadzać danych do kolumn w ten sposób; mysql> zaktualizuj zestaw tabel last_update = last_monitor = now () gdzie id = 1;
Wahinya Brian