Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][PDO] Błąd podczas bindowania
Forum PHP.pl > Forum > Przedszkole
mattix19
Witam,
mam taki kod:
  1. $tab = array(':tytul' => $nazwa, ':autor' => $autor,':cena' => $cena, ':typ' => $typ,':opis' => $opis, ':rodzaj' => $rodzaj,
  2. ':stanowiskwgarazu' => $garaz, ':katnachyleniadachu' => $kat, ':podpiwniczenie' => $piwnica, ':poddasze' => $poddasze, ':kominek' => $kominek,
  3. ':szerokoscdzialki' => $szerokosc, ':dlugoscdzialki' => $dlugosc, ':powuzytkowa' => $pow_uzytk,
  4. ':powzabudowy' => $pow_zabud, ':powdachu' => $pow_dach, ':typkotla' => $typ_ogrzewania, ':idpracowni' => $id_pracowni , ':idkat' => $id_kat);
  5.  
  6. $stm = $this->db->prepare("INSERT INTO projekty_projekt (tytul, autor, cena, typ, opis, rodzaj, stanowisk_w_garazu, kat_nachylenia_dachu, podpiwniczenie, poddasze, kominek, szerokosc_dzialki, dlugosc_dzialki, pow_uzytkowa, pow_zabudowy, pow_dachu, typ_kotla, projekty_pracownie_id_pracowni, projekty_kategorie_id_kategorii )
  7. VALUES (:tytul, :autor, :cena, :typ, :opis, :rodzaj, :stanowiskwgarazu, :katnachyleniadachu, :podpiwniczenie, :poddasze, :kominek, :szerokoscdzialki, :dlugoscdzialki, :powuzytkowa, :powzabudowy, :powdachu, :typkotla, :idpracowni, :idkat )");
  8. foreach($tab as $k => $v){
  9.  
  10. if(is_int($v))
  11. $param = PDO::PARAM_INT;
  12. elseif(is_bool($v))
  13. $param = PDO::PARAM_BOOL;
  14. elseif(is_null($v))
  15. $param = PDO::PARAM_NULL;
  16. elseif(is_string($v))
  17. $param = PDO::PARAM_STR;
  18. else
  19. $param = '';
  20. if($param)
  21. $stm->bindValue($k, $v, $param);
  22. }
  23. $il = $stm->execute();

Problem polega na tym ze jak robie dodawanie do bazy to pojawia sie taki blad:
  1. Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /home/.../admin.class.php on line 297

jednak gdy robie bindowanie z reki bez petli foreach:
  1. $stm->bindValue(':tytul', $nazwa);
  2. $stm->bindValue(':autor', $autor);
  3. $stm->bindValue(':cena', $cena);
  4. $stm->bindValue(':typ', $typ);
  5. $stm->bindValue(':opis', $opis);
  6. $stm->bindValue(':rodzaj', $rodzaj);
  7. $stm->bindValue(':stanowiskwgarazu', $garaz);
  8. $stm->bindValue(':katnachyleniadachu', $kat);
  9. $stm->bindValue(':podpiwniczenie', $piwinica);
  10. $stm->bindValue(':poddasze', $poddasze);
  11. $stm->bindValue(':kominek', $kominek);
  12. $stm->bindValue(':szerokoscdzialki', $szerokosc);
  13. $stm->bindValue(':dlugoscdzialki', $dlugosc);
  14. $stm->bindValue(':powuzytkowa', $pow_uzytk);
  15. $stm->bindValue(':powzabudowy', $pow_zabud);
  16. $stm->bindValue(':powdachu', $pow_dach);
  17. $stm->bindValue(':typkotla', $typ_ogrzewania);
  18. $stm->bindValue(':idpracowni', $id_pracowni);
  19. $stm->bindValue(':idkat', $id_kat);

to zamiast 400 roznych rekordow pojawia mi sie tylko w bazie 1, pierwszy. Caly kod powinien sie wykonac okolo 400 razy bo tyle rekordow pobralem z xml. Tablice stworzona mam dobrze bo var_dump ja ladnie wyswietlil. Problem twki w samym dodawaniu. Dlaczego dodaje mi jeden rekord i jak z powyzszego zapytania pozbyc sie tego bledu?
Crozin
Jeżeli zmienna nie jest typu int/string/bool/null zmiennej $param przypisujesz pusty string. Następnie masz IFa, który zbinduje wartość tylko w przypadku, gdy zmienna $param ma wartość, a ta nie będzie miała wartości (pusty string jest tożsamy z FALSE przy zwykłym porównaniu), jeżeli zmienna będzie obiektem, tablicą bądź typem float/double. else $param = ''; zamień na else $param = PDO::PARAM_STR;.
mattix19
dobra to dziala ale w petli for nadal dodaje mi tylko jeden 1 rekord. Czy musze zamknac jakos polaczenie z baza zeby dodal wszystkie? closeCursor nie dziala.
Crozin
Ale nie widać tutaj żadnej pętli, która miałaby dodać więcej niż jeden rekord. Jeżeli taka istnieje, to domyślam się, że obejmuje ona pow. kod, w takim wypadku:
1. PrepareStatement powinieneś przenieść przed pętle - nie ma potrzeby każdorazowo tego wykonywać.
2. PDOStatement::closeCursor() powinieneś umieścić zaraz za PDOStatement::execute()
mattix19
wyglada to dokladnie tak:
  1. //parser to tablica z danymi z xml.
  2. $stm = $this->db->prepare("INSERT INTO projekty_projekt (tytul, autor, cena, typ, opis, rodzaj, stanowisk_w_garazu, kat_nachylenia_dachu, podpiwniczenie, poddasze, kominek, szerokosc_dzialki, dlugosc_dzialki, pow_uzytkowa, pow_zabudowy, pow_dachu, typ_kotla, projekty_pracownie_id_pracowni, projekty_kategorie_id_kategorii ) VALUES (:tytul, :autor, :cena, :typ, :opis, :rodzaj, :stanowiskwgarazu, :katnachyleniadachu, :podpiwniczenie, :poddasze, :kominek, :szerokoscdzialki, :dlugoscdzialki, :powuzytkowa, :powzabudowy, :powdachu, :typkotla, :idpracowni, :idkat )");
  3.  
  4. for ($i=0; $i < count($parser); $i++) {
  5. $tab = array(':tytul' => $nazwa, ':autor' => $autor,':cena' => $cena, ':typ' => $typ,':opis' => $opis, ':rodzaj' => $rodzaj,
  6. ':stanowiskwgarazu' => $garaz, ':katnachyleniadachu' => $kat, ':podpiwniczenie' => $piwnica, ':poddasze' => $poddasze, ':kominek' => $kominek,
  7. ':szerokoscdzialki' => $szerokosc, ':dlugoscdzialki' => $dlugosc, ':powuzytkowa' => $pow_uzytk,
  8. ':powzabudowy' => $pow_zabud, ':powdachu' => $pow_dach, ':typkotla' => $typ_ogrzewania, ':idpracowni' => $id_pracowni , ':idkat' => $id_kat);
  9.  
  10. foreach($tab as $k => $v){
  11.  
  12. if(is_int($v))
  13. $param = PDO::PARAM_INT;
  14. elseif(is_bool($v))
  15. $param = PDO::PARAM_BOOL;
  16. elseif(is_null($v))
  17. $param = PDO::PARAM_NULL;
  18. elseif(is_string($v))
  19. $param = PDO::PARAM_STR;
  20. else
  21. $param = PDO::PARAM_STR;
  22. if($param)
  23. $stm->bindValue($k, $v, $param);
  24. }
  25. $il = $stm->execute();
  26. $stm->closeCursor();
  27. }


i w bazie pojawia sie tylko jeden rekord. Powinno okolo 400.
Crozin
1. Nie wiem czy skonfigurowałeś PDO by rzucało wyjątkami czy nie, upewnij się jednak, że PDOStatement::execute() zawsze zwraca TRUE.
2. Nie widzę, byś gdziekolwiek zmieniał zawartość zmiennych przekazywanych jako parametry zapytania. Cały czas operujsz na tych samych danych.
mattix19
nie no zmienne sa tworzone juz w petli porostu nie dodalem tu. dane sa dobrze zrobione zapytanie tez lecz nie mam pojecia czemu to nie rusza.... execute() zwraca true tylko za 1 obiegiem petli potem juz false...
Crozin
No to jeżeli PDOStatement::execute() zwraca FALSE masz jakiś błąd. Sprawdź jaki to dokładnie błąd: http://www.php.net/manual/en/pdo.error-handling.php
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.