Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] update w pętli
Forum PHP.pl > Forum > Przedszkole
max_mcee
Witam

Rekordy wyświetlam w pętli z bazy danych:


I załóżmy, że chcemy zaktualizować dane w bazie, więc pewnie trzeba to zrobić w pętli. I tutaj mam problem:

  1. if(isset($_POST['spr'])) {
  2. $ilosc_wierszy = mysql_num_rows($wynik);
  3. //$id = $dane['id'];
  4.  
  5. for ($z=1; $z<= $ilosc_wierszy; $z++) {
  6.  
  7. mysql_query("UPDATE user SET (1 = '$_POST[1]', 2 = '$_POST[2]', 3 = '$_POST[3]') WHERE id ='$z'") or die (mysql_error());
  8.  
  9. }
  10. }


Jak zaktualizować te dane w bazie ?
lobopol
Bez nawiasu po set
  1. UPDATE user SET 1 = '{$_POST[1]}', 2 = '{$_POST[2]}', 3 = '{$_POST[3]}' WHERE id ='$z'
max_mcee
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 '1 = 'W', 2 = 'W', 3 = 'W' WHERE id ='1'' at line 1

Niestety nadal nie działa.
tolomei
Witaj.

  1. mysql_query("UPDATE `user` SET `1` = '".addslashes($_POST[1])."', `2` = '".addslashes($_POST[2])."', `3` = '".addslashes($_POST[3])."' WHERE id = ".$z.") or die (mysql_error());


Pozdrawiam.
max_mcee
Teraz działa.
Jednak aktualizuje tylko ostatni wiersz. Może pokaże cały kod.

  1. <?php
  2.  
  3. include("config.php");
  4. $dni = array(
  5. '',
  6. 'Pon',
  7. 'Wto',
  8. 'Śro',
  9. 'Czw',
  10. 'Pią',
  11. 'Sob',
  12. 'Nie',
  13. );
  14.  
  15. $wiersz1 = '';
  16. $wiersz2 = '';
  17.  
  18. for($i=1;$i<=date('t');$i++)
  19. {
  20. $wiersz1 .= '<td>'.$dni[date('N', mktime(0, 0, 0, date('n'), $i, date('Y')))].'</td>';
  21. $wiersz2 .= "<td>$i</td>";
  22. }
  23.  
  24. echo '<form method="POST" action="zapis.php">';
  25. echo '<table>';
  26. echo '<tr>';
  27. echo '<td>Imię</td>';
  28. echo $wiersz2;
  29. echo '</tr>';
  30. echo '<tr>';
  31. echo '<td>i nazwisko</td>';
  32. echo $wiersz1;
  33. echo '</tr>';
  34. $sql = "SELECT * FROM user";
  35. $wynik = mysql_query($sql);
  36.  
  37. $tablica = array();
  38. while($dane = mysql_fetch_array($wynik)) {
  39.  
  40. echo '<tr><td><input type="hidden" name="id" value="'.$dane['id'].'" />'.$dane['name']."</td>";
  41. for ($d=1; $d<=date('t'); $d++){
  42. echo '<td><input type="text" name="'.$d.'" value="'.$dane[$d].'"></td>';
  43.  
  44. }
  45. }
  46. echo'</tr>';
  47. echo'</table>';
  48. echo'<input type="hidden" name="spr" value="1" />';
  49. echo'<input type="submit" value="ZAPISZ" />';
  50. echo'</form>';
  51.  
  52.  
  53.  
  54. if(isset($_POST['spr'])) {
  55. $ilosc_wierszy = mysql_num_rows($wynik);
  56. //$id = $dane['id'];
  57.  
  58. for ($z=1; $z<= $ilosc_wierszy; $z++) {
  59.  
  60. mysql_query("UPDATE `user` SET `1` = '".$_POST[1]."', `2` = '".$_POST[2]."', `3` = '".$_POST[3]."' WHERE id ='".$z."'") or die (mysql_error());
  61.  
  62. }
  63.  
  64. }
  65.  
  66. ?>


jak to naprawić ?
Niktoś
Czym jest $_POST[1] i $_POST[2] ?- jeśli któreś id pola ma nazwę zaczynającą się od liczby to jest to błąd.
max_mcee
Tak wygląda baza:
To błąd ?

Niktoś
Przecież ja nie mówiłem o bazie tylko,tylko o polach input do których odwołujesz się $_POST["cośtam"];
Ty się jakoś w ogóle dziwnie odwołujesz do tablicy $_POST jak do tablicy indeksowanej ,a jest ona przecież hiperglobalną asocjacyjną.
max_mcee
  1. <tr><td><input type="hidden" name="id" value="1" />user1</td><td><input type="text" name="1" value="r"></td>
  2. <td><input type="text" name="2" value="r"></td>
  3. <td><input type="text" name="3" value="r"></td>
  4.  
  5. itd.
Niktoś
<input type="text" name="1" value="r"></td>
<input type="text" name="2" value="r"></td>
<input type="text" name="3" value="r">

To co jest pogrubione jest nie poprawne.Wiesz jak będzie wyglądała tablica POST?Przykładowo,to coś takiego:
1=1
2=2
3=3
4=4
itd.
I jak potem chcesz się odwoływać?Powiedz co jest kluczem ,a co wartością?
max_mcee
Chciałem się odwoływać, do id użytkownika.

załóżmy
$_POST[1] = W
$_POST[2] = R

jakoś nie mogę zrozumieć Twojego toku myślenia.. Możesz to dokładnie opisać ?
Niktoś
  1. <?php
  2.  
  3. include("config.php");
  4.  
  5. $dni = array(
  6.  
  7. '',
  8.  
  9. 'Pon',
  10.  
  11. 'Wto',
  12.  
  13. 'Śro',
  14.  
  15. 'Czw',
  16.  
  17. 'Pią',
  18.  
  19. 'Sob',
  20.  
  21. 'Nie',
  22.  
  23. );
  24.  
  25. $wiersz1 = '';
  26.  
  27. $wiersz2 = '';
  28.  
  29. for($i=1;$i<=date('t');$i++)
  30.  
  31. {
  32.  
  33. $wiersz1 .= '<td>'.$dni[date('N', mktime(0, 0, 0, date('n'), $i, date('Y')))].'</td>';
  34.  
  35. $wiersz2 .= "<td>$i</td>";
  36.  
  37. }
  38.  
  39. echo '<form method="POST" action="zapis.php">';
  40.  
  41. echo '<table>';
  42.  
  43. echo '<tr>';
  44.  
  45. echo '<td>Imię</td>';
  46.  
  47. echo $wiersz2;
  48.  
  49. echo '</tr>';
  50.  
  51. echo '<tr>';
  52.  
  53. echo '<td>i nazwisko</td>';
  54.  
  55. echo $wiersz1;
  56.  
  57. echo '</tr>';
  58.  
  59. $sql = "SELECT * FROM user";
  60.  
  61. $wynik = mysql_query($sql);
  62.  
  63. $tablica = array();
  64. while($dane = mysql_fetch_array($wynik)) {
  65.  
  66. echo '<tr><td><input type="hidden" name="id" value="'.$dane['id'].'" />'.$dane['name']."</td>";
  67.  
  68. for ($d=1; $d<=date('t'); $d++){
  69.  
  70. echo '<td><input type="text" name="nazwa'.$d.'" value="'.$dane[$d].'"></td>';
  71.  
  72. }
  73.  
  74. }
  75.  
  76. echo'</tr>';
  77.  
  78. echo'</table>';
  79.  
  80. echo'<input type="hidden" name="spr" value="1" />';
  81.  
  82. echo'<input type="submit" value="ZAPISZ" />';
  83.  
  84. echo'</form>';
  85.  
  86. if(isset($_POST['spr'])) {
  87.  
  88. $ilosc_wierszy = mysql_num_rows($wynik);
  89.  
  90. //$id = $dane['id'];
  91.  
  92. for ($z=1; $z<= $ilosc_wierszy; $z++) {
  93.  
  94. mysql_query("UPDATE `user` SET `1` = '".$_POST['nazwa1']."', `2` = '".$_POST['nazwa2']."', `3` = '".$_POST['nazwa3']."' WHERE id ='".$z."'") or die (mysql_error());
  95.  
  96. }
  97.  
  98. }
  99.  
  100. ?>
mortus
@Niktoś: Zapis:
  1. <input type="text" name="1" value="r">
  2. <input type="text" name="2" value="r">
  3. <input type="text" name="3" value="r">

jest niepoprawny, ale tylko z punktu widzenia specyfikacji (X)HTML. W PHP kluczem jest zawsze indeks w tablicy $_POST, a wartością wartość elementu z tablicy $_POST o wspomnianym indeksie. To nie jest błąd pod względem obslugi po stronie PHP.
No i nadal nie będzie działać.

@max_mcee: Najpierw kod:
  1. while($dane = mysql_fetch_array($wynik)) {
  2. echo '<tr><td><input type="hidden" name="id" value="'.$dane['id'].'" />'.$dane['name']."</td>";
  3. for ($d=1; $d<=date('t'); $d++){
  4. echo '<td><input type="text" name="'.$d.'" value="'.$dane[$d].'"></td>';
  5. }
  6. }

W pętli while generujesz wiele elementów o nazwie id (name="id"), a po zatwierdzeniu formularza wysyłany jest identyfikator tylko jednego, ostatniego z tych elementów. Dzieje się tak właśnie dlatego, że elementy mają taką samą nazwę. Podobnie jest w przypadku pętli for. W momencie, gdy chcesz edytować wiele wierszy w tabeli musisz posłużyć się nazwami "tablicowymi", tj. takimi, które po zatwierdzeniu formularza przesyłają w $_POST tablice. Wyglądałoby to tak:
  1. while($dane = mysql_fetch_array($wynik)) {
  2. echo '<tr><td><input type="hidden" name="ids[]" value="'.$dane['id'].'" />'.$dane['name']."</td>";
  3. for ($d=1; $d<=date('t'); $d++){
  4. echo '<td><input type="text" name="col'.$d.'_vals[]" value="'.$dane[$d].'"></td>';
  5. }
  6. }

Przesłane w ten sposób dane odbierasz w taki sposób:
  1. if(isset($POST['spr'])) {
  2. foreach($_POST['ids'] as $key => $value) {
  3. $id_rekordu = $_POST['ids'][$key];
  4. $kolumna_1 = $_POST['col1_vals'][$key];
  5. $kolumna_2 = $_POST['col2_vals'][$key];
  6. // itd.
  7. mysql_query("UPDATE `user` SET `1` = $kolumna_1, `2` = $kolumna_2 WHERE `id` = $id_rekordu");
  8. }
  9. }

Pozostaje jeszcze kwestia optymalności skryptu. Niestety wykonywanie UPDATE-ów w pętli nie jest optymalnym rozwiązaniem, lepiej posłużyć się tutaj zapytaniem MULTI-INSERT z opcją ON DUPLICATE KEY UPDATE. Ale o tym może później, jak już ogarniesz powyższy kod.
max_mcee
Nadal jest problem przy takim rozwiązaniu, ponieważ jak wpisuje w pierwszym polu W to nic się nie zmienia, a jak wpisuje w drugie pole W to i w pierwsze się wpisuje automatycznie.
mortus
Cytat(max_mcee @ 1.04.2012, 18:31:38 ) *
Nadal jest problem przy takim rozwiązaniu, ponieważ jak wpisuje w pierwszym polu W to nic się nie zmienia, a jak wpisuje w drugie pole W to i w pierwsze się wpisuje automatycznie.

Nie ma innego rozwiązania, a to które podałem jest jedynym słusznym. Musisz je tylko u siebie wprowadzić... czy to zrobiłeś, nie wiem, bo nie widzę. Mam tylko nadzieję, że w ogóle wyrzuciłeś pętle for po zmiennej $z, bo ta pętla w ogóle nie powinna się tam znajdować.

Nie uważam, żeby napisanie całości za Ciebie było dobrym podejściem, więc pokaż kod, sprawdzę, czy są błędy i gdzie, i podpowiem co trzeba naprawić.


Cytat(Niktoś @ 1.04.2012, 18:37:33 ) *
Czy manual kłamie?
Tablica asocjacyjna charakteryzuje się kluczami do których się odwołujesz,nie odwołujesz się do indexów.
Znajdź mi jeden choćby przykład w manualu, gdzie odwołuje się do wartości poprzez indeksy jak $_POST[0],$_POST[1],$_POST[2].

Zdanie wyrwane z kontekstu o niczym nie świadczy. To, że $_POST jest tablicą asocjacyjną to ja wiem doskonale. Ale w tablicy asocjacyjnej mogą się znaleźć również elementy indeksowane liczbami, więc nie ma w ogóle o czym gadać. Przykłady w manualu PHP są dostosowane do specyfikacji (X)HTML. Skoro zatem name w elemencie HTML nie może zaczynać się cyfrą, to i tak jest, i będzie w każdym z przykładów, jaki znajdziesz, co nie oznacza, że pole o nazwie 1 nie zostanie przesłane, i co nie oznacza, że wartością pola o nazwie 1 nie będzie inna z góry określona wartość. Klucze i wartości się nie pomieszają tylko dlatego, że nazwa pola będzie cyfrą. Najpierw to przetestuj, a później zgłaszaj sprzeciwy... ja testowałem kiedyś przesyłanie danych przez pola formularza o niewłaściwych nazwach i... działa.

Dobra kończę offtop. Widzę, że kolega Niktoś usunął swoją odpowiedź, ech...
max_mcee
  1. <?php
  2.  
  3. include("config.php");
  4.  
  5. $dni = array(
  6.  
  7. '',
  8.  
  9. 'Pon',
  10.  
  11. 'Wto',
  12.  
  13. 'Śro',
  14.  
  15. 'Czw',
  16.  
  17. 'Pią',
  18.  
  19. 'Sob',
  20.  
  21. 'Nie',
  22.  
  23. );
  24.  
  25. $wiersz1 = '';
  26.  
  27. $wiersz2 = '';
  28.  
  29. for($i=1;$i<=date('t');$i++)
  30.  
  31. {
  32.  
  33. $wiersz1 .= '<td>'.$dni[date('N', mktime(0, 0, 0, date('n'), $i, date('Y')))].'</td>';
  34.  
  35. $wiersz2 .= "<td>$i</td>";
  36.  
  37. }
  38.  
  39. echo '<form method="POST" action="zapis.php">';
  40.  
  41. echo '<table>';
  42.  
  43. echo '<tr>';
  44.  
  45. echo '<td>Imię</td>';
  46.  
  47. echo $wiersz2;
  48.  
  49. echo '</tr>';
  50.  
  51. echo '<tr>';
  52.  
  53. echo '<td>i nazwisko</td>';
  54.  
  55. echo $wiersz1;
  56.  
  57. echo '</tr>';
  58.  
  59. $sql = "SELECT * FROM user";
  60.  
  61. $wynik = mysql_query($sql);
  62.  
  63. $tablica = array();
  64. while($dane = mysql_fetch_array($wynik)) {
  65.  
  66. echo '<tr><td><input type="hidden" name="ids[]" value="'.$dane['id'].'" />'.$dane['name']."</td>";
  67.  
  68. for ($d=1; $d<=date('t'); $d++){
  69.  
  70. echo '<td><input type="text" name="col'.$d.'_vals[]" value="'.$dane[$d].'"></td>';
  71.  
  72. }
  73.  
  74. }
  75.  
  76. echo'</tr>';
  77.  
  78. echo'</table>';
  79.  
  80. echo'<input type="hidden" name="spr" value="1" />';
  81.  
  82. echo'<input type="submit" value="ZAPISZ" />';
  83.  
  84. echo'</form>';
  85.  
  86. if(isset($_POST['spr'])) {
  87.  
  88.  
  89. foreach($_POST['ids'] as $key => $value) {
  90. $id_rekordu = $_POST['ids'][$key];
  91. $kolumna_1 = $_POST['col1_vals'][$key];
  92. $kolumna_2 = $_POST['col2_vals'][$key];
  93. // itd.
  94. mysql_query("UPDATE `user` SET `1` = $kolumna_1, `2` = $kolumna_2 WHERE `id` = $id_rekordu") or die (mysql_error());;
  95. }
  96.  
  97.  
  98. }
  99.  
  100. ?>


To rozwiązanie nie zmienia zawartości bazy, nic się nie dzieje, przeanalizowałem całoś co mi wysłałeś i rozumiem mechanizm działania, jednak nie wiem czemu nie zapisuje danych do bazy.

Unknown column 'w' in 'field list'
mortus
Niektóre z aktualizowanych wartości są łańcuchami znaków i trzeba je objąć apostrofami:
  1. mysql_query("UPDATE `user` SET `1` = '{$kolumna_1}', `2` = '{$kolumna_2}' WHERE `id` = $id_rekordu") or die (mysql_error());


EDIT:
Oczywiście zauważ, że brakuje reszty kolumn. Kolumny do zapytania możesz dodawać dynamicznie (np. w pętli for) lub tak, jak zaprezentowałem w przykładzie. Kolumn jest dużo, więc lepszym rozwiązaniem będzie pętla.
max_mcee
Nadal ten sam błąd:

  1. Unknown column 'w' in 'field list'


  1. mysql_query("UPDATE `user` SET `1` = {$kolumna_1}, `2` = {$kolumna_2} WHERE `id` = $id_rekordu") or die (mysql_error());


bo rozumiem, że to powinno działać, nawet jeśli są tylko 2 pola ?
Bo w zasadzie updatem aktualizujemy tylko te pola które chcemy. Dobrze rozumiem ?
mortus
Nadal brakuje apostrofów, przyjrzyj się uważnie mojej poprzedniej wypowiedzi. Jeśli wartość (to co po znaku =, a nie przed), która ma być umieszczona w komórce jest napisem/łańcuchem znaków, to trzeba ją objąć apostrofami, w przeciwnym przypadku zostanie ona potraktowana, jak kolumna.

Oczywiście w ramach testów możesz aktualizować tylko dwie kolumny.
max_mcee
Ok działa smile.gif

Czyli twierdzisz, że zamiast UPDATE warto by użyć:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
mortus
Tak, trzeba tylko w pętli (tej pętli foreach) wygenerować odpowiednie zapytanie (jako łańcuch znaków), co w efekcie dałoby np. takie zapytanie:
  1. INSERT INTO `user` (`id`, `1`, `2`) VALUES
  2. (1, 'W', 'R'),
  3. (2, 'R', 'R')
  4. ON DUPLICATE KEY UPDATE
Potem trzeba to zapytanie wykonać (choć wykonywać powinno się co określoną liczbę kroków).
  1. $sql = "INSERT INTO `user` (`id`, `1`, `2`) VALUES";
  2. foreach($_POST['ids'] as $key => $value) {
  3. $id_rekordu = $_POST['ids'][$key];
  4. $kolumna_1 = $_POST['col1_vals'][$key];
  5. $kolumna_2 = $_POST['col2_vals'][$key];
  6. // itd.
  7. $sql = " ({$id_rekordu}, '{kolumna_1}', '{$kolumna_2}'),"; // tutaj generujemy zapytanie
  8. // i wykonujemy je np. co 50 rekordów, lub, jeśli nie będzie ich więcej
  9. if($key + 1 % 50 == 0 || $key + 1 == count($_POST['ids'])) { // tutaj odpowiednie warunki, trzeba pamiętać, że w pętli foreach niezdefiniowane indeksy liczone są od 0, można posłużyć się pętlą for
  10. $sql = substr($sql, -1); // preparujemy zapytanie sql, trzeba wyciąć ostatni przecinek
  11. $sql .= " ON DUPLICATE KEY UPDATE"; // i dopisujemy klauzulę SQL
  12. mysql_query($sql); // i w końcu możemy zapytanie wykonać
  13. $sql = "INSERT INTO `user` (`id`, `1`, `2`) VALUES "; // gdyby w tabeli było więcej rekordów, aniżeli wielokrotność 50 to zapytanie budujemy od nowa
  14. }
  15. }
max_mcee
ohmy.gif

Dziękuje za pomoc, przeanalizuje to co napisałeś i w razie czego zapytam co i jak, ale pewnie trochę czasu mi zejdzie 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.