Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP][MySQL]Aktualizacja wartości jednym zapytaniem z nietypową budową tabeli w bazie
Majkelo23
post 22.05.2012, 06:46:15
Post #1





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

Ostrzeżenie: (0%)
-----


Jak przy takiej budowie tabeli:

Cytat
config_name | config_value
nazwa _______________ 1
nazwa2 _______________ 343434
nazwa3_______________ ifejfiesfjesifj


Zaktualizować za jednym zamachem wszystkie rekordy? Przy aktualizacji jednego, wyglądałoby to tak:

  1. UPDATE `config` SET config_value = 'wartosc' WHERE config_name = 'nazwa';


Da się jakoś skonstruować to zapytanie tak, aby XX takich rekordów zaktualizować za jednym zamachem?
Go to the top of the page
+Quote Post
bastard13
post 22.05.2012, 06:52:17
Post #2





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Jeśli chcesz wszystkie to:
  1. UPDATE `config` SET config_value = 'wartosc';

a wybrane:
  1. UPDATE `config` SET config_value = 'wartosc' WHERE config_name IN ('n1', 'n2', 'n3');


Ten post edytował bastard13 22.05.2012, 06:53:48


--------------------
Go to the top of the page
+Quote Post
Majkelo23
post 22.05.2012, 06:56:22
Post #3





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

Ostrzeżenie: (0%)
-----


A jeśli chcę pojedyncze rekordy zmieniać w pojedynczych polach? To zapytanie ma wyglądać tak:

  1. UPDATE `config` SET config_value IN ('wartosc', 'wartosc2', 'wartosc') WHERE config_name IN ('n1', 'n2', 'n3');


questionmark.gif
Go to the top of the page
+Quote Post
bostaf
post 22.05.2012, 11:26:05
Post #4





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


Cytat(Majkelo23 @ 22.05.2012, 07:56:22 ) *
A jeśli chcę pojedyncze rekordy zmieniać w pojedynczych polach? To zapytanie ma wyglądać tak:

  1. UPDATE `config` SET config_value IN ('wartosc', 'wartosc2', 'wartosc') WHERE config_name IN ('n1', 'n2', 'n3');


questionmark.gif

Nie. Klauzuli IN można używać tylko wewnątrz klauzuli WHERE. Wyrażenie SET musi mieć konkretną wartość z dozwolonego zakresu typów wartości.

A odpowiadając na pierwsze pytanie: jeśli wartości są różne dla każdego wpisu to nie da się. Nie da się czystym zapytaniem MySQL. Ale jeśli możesz wykorzystać PHP, to mógłbyś posłużyć się PDO, spreparować zapytanie i wykonać je w pętli dla tablicy wartości:
  1. $dane = array (
  2. 'nazwa1' => 'wartość',
  3. 'nazwa 2' => 'coś innego',
  4. 'n4m3' => 'v4lu3'
  5. );
  6. $stmt = $dbh->prepare("UPDATE `config` SET `config_value` = ? WHERE `config_name` = ?");
  7. foreach($dane as $nazwa => $wartosc) {
  8. $stmt->execute(array($wartosc, $nazwa));
  9. }

Go to the top of the page
+Quote Post
Crozin
post 22.05.2012, 11:37:58
Post #5





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
A odpowiadając na pierwsze pytanie: jeśli wartości są różne dla każdego wpisu to nie da się. Nie da się czystym zapytaniem MySQL.
Formalnie rzecz biorąc to jak najbardziej da się, ale nie będzie to za ładne zapytanie, coś w stylu:
  1. UPDATE config SET config_value = CASE config_name WHEN "nazwa1" THEN "nowa wartość 1" WHEN "nazwa2" THEN "nowa wartość 2" WHEN "nazwa3" THEN "nowa wartość 3" END CASE WHERE config_name IN ("nazwa1", "nazwa2", "nazwa3");
Ale taki potworek to koszmar w "utrzymaniu", powinieneś w obrębie jednej transakcji wykonać n zapytań UPDATE, tak jak pokazał to @bostaf.
Go to the top of the page
+Quote Post
Majkelo23
post 22.05.2012, 21:26:20
Post #6





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

Ostrzeżenie: (0%)
-----


Crozin, próbując użyć Twojego zapytania:
  1. UPDATE config SET config_value = CASE config_name WHEN "version" THEN "1.0.1" WHEN "meta" THEN "test" END CASE WHERE config_name IN ("version", "meta");


Otrzymuję błąd:

Cytat
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHERE config_name IN ("version", "meta")' at line 1


Co jest nie tak?
Go to the top of the page
+Quote Post
Crozin
post 22.05.2012, 22:29:20
Post #7





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Powinno być:
  1. [...] SET config_value = (CASE WHEN config_name = "version" THEN ... WHEN config_name = "..." ...) WHERE config_name [...]
Ale naprawdę nie powinieneś wykonywać takiego zapytania - seria n normalnych zapytań to zdecydowanie lepsze rozwiązanie w tym przypadku.
Go to the top of the page
+Quote Post
Majkelo23
post 22.05.2012, 22:32:18
Post #8





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

Ostrzeżenie: (0%)
-----


Ale pod względem optymalnym? Czemu niby? Przecież tutaj mam jedno zapytanie, a tak będzie ich ok. 60.
Go to the top of the page
+Quote Post
Crozin
post 22.05.2012, 22:39:08
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Ilość zapytań i ich złożoność to dwie zupełnie odmienne sprawy. Mniejsza ilość zapytań nie musi oznaczać wzrostu wydajności.
2. Tutaj domyślam się, że chodzi o aktualizację jakiejś ogólnej konfiguracji strony/fragmentu strony. Zapewne ten kod nie jest wykonywany 20 razy na sekundę, tak więc aspekty wydajności są nieistotne. Natomiast czytelność i prostota kodu jak najbardziej odgrywają tutaj znaczącą rolę.
Go to the top of the page
+Quote Post
Majkelo23
post 22.05.2012, 22:42:50
Post #10





Grupa: Zarejestrowani
Postów: 226
Pomógł: 17
Dołączył: 13.02.2012

Ostrzeżenie: (0%)
-----


Cytat(Crozin @ 22.05.2012, 23:39:08 ) *
2. Tutaj domyślam się, że chodzi o aktualizację jakiejś ogólnej konfiguracji strony/fragmentu strony.


Dokładnie. OK, zrobię jak napisałeś,dzięki wink.gif
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.05.2024 - 07:23