Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zwiększenie wszystktim rekordom `sort_id` o jeden
Forum PHP.pl > Forum > PHP
Grim90
Witam serdecznie smile.gif
Piszę skrypt PHP / MySQL na własne potrzeby i mam taką oto sytuację oraz problem - przejdźmy zatem do konkretów:
Dodaję za pomocą formularza rekord wraz z opcją wpisania ID (sort_id w bazie). Sortowanie na stronie leci za pomocą właśnie tego sort_id, więc chciałbym wprowadzić, że jeśli przykładowo mam rekordy z sort_id 1, 2, 3, 4, 5, oraz gdy wpiszę w formularzu nowego rekordu przykładowo id 3, to istniejącym już rekordom z sort_id 3, 4, 5 zostanie nadany UPDATE, gdzie zostanie dodany +1 do ich sort_id, czyli będą wynosić 4, 5, 6, a tamten doda się z sort_id 3.

Zrobiłem już coś takiego:
  1. $name = safe_it($_POST["name"]);
  2. $description = safe_it($_POST["description"]);
  3. $category = safe_it($_POST["category"]);
  4. $id = safe_it($_POST["id"]);
  5. $get = mysql_query("SELECT * FROM `server_boards` WHERE `sort_id` >= '$id' ORDER BY `sort_id`");
  6. while($board = mysql_fetch_assoc($get))
  7. {
  8. $getSort = $board["sort_id"];
  9. mysql_query("UPDATE `server_boards` SET `sort_id` = '" .($getSort + 1). "' WHERE `sort_id` = '$getSort'");
  10. }
  11.  
  12. mysql_query("INSERT INTO `server_boards` VALUES(NULL, '$name', '$description', '$category', '$id')");
  13. header("Location: ?goto=forum&action=boards");


Niestety, po zrobieniu tego wszystko się pruje, znaczy się mam wyniki, które pierwotnie były (sort_id) 1, 2, 3, 4, 5, 6, 7, zmieniły się w 1, 1, 1, 6, 6, 8, 8. Oczywiście nowy rekord został dodany prawidłowo po tym...

Zatem, ma ktoś jakąś propozycję rozwiązania tego problemu?

Pozdrawiam i z góry dziękuję za chęci pomocy smile.gif
everth
Pierwsze zapytanie - podbijamy rekordy:
  1. UPDATE `server_boards` SET `sort_id` = `sort_id`+1 WHERE `sort_id` >= '$id';

Drugie zapytanie - wstawiamy rekord:
  1. INSERT INTO `server_boards` VALUES('$id', '$name', '$description', '$category', '$id'); /* przy założeniu że sort_id to twój klucz główny i jest na pierwszym miejscu

Najlepiej byłoby wykonać oba zapytania w pojedynczej transakcji dla bezpieczeństwa
Grim90
Działa wyśmienicie, dziękuję bardzo smile.gif

Cieszę się, że mogę na was liczyć w razie bezradności.

Kurczę, o transakcji nie mam zielonego pojęcia póki co, więc będę musiał sobie zarezerwować trochę czasu na poszerzenie na ten temat wiedzy.

W związku z tym mam jeszcze takie pytanko - czy to może być w jakiś sposób niebezpieczne, skoro piszesz o bezpieczeństwie? Dodam (gdyby ktoś pytał), że funkcja safe_it wygląda tak:

  1. function safe_it($str)
  2. {
  3. }
everth
Z tym bezpieczeństwem to nie chodzi o jakieś Sql Injection tylko o zachowanie spójności. Jeśli drugie zapytanie z jakiegokolwiek powodu się nie wykona to w kluczu bazy zostaje dziura (a prawdopodobnie coś w innej tabeli się do tego klucza odwołuje), w drugiej sytuacji (pierwsze zapytanie się nie wykonuje) jest trochę lepiej bo insert też się nie wykona.
Transakcja gwarantuje ci że stan tabeli zmieni się tylko wtedy gdy oba zapytania wykonają się poprawnie. Żeby mieć obsługę transakcji to zmień silnik tej tabeli na InnoDB.
Grim90
Rozumiem już,
Dziękuję bardzo za pomoc i wyjaśnienie.

Pozdrawiam serdecznie smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.