Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP][PDO] Błąd podczas bindowania
mattix19
post
Post #1





Grupa: Zarejestrowani
Postów: 32
Pomógł: 0
Dołączył: 11.07.2010

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


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?

Ten post edytował mattix19 31.03.2013, 13:03:39


--------------------
CI
Go to the top of the page
+Quote Post
Crozin
post
Post #2





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

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


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;.
Go to the top of the page
+Quote Post
mattix19
post
Post #3





Grupa: Zarejestrowani
Postów: 32
Pomógł: 0
Dołączył: 11.07.2010

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


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.


--------------------
CI
Go to the top of the page
+Quote Post
Crozin
post
Post #4





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

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


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()
Go to the top of the page
+Quote Post
mattix19
post
Post #5





Grupa: Zarejestrowani
Postów: 32
Pomógł: 0
Dołączył: 11.07.2010

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


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.


--------------------
CI
Go to the top of the page
+Quote Post
Crozin
post
Post #6





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

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


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.
Go to the top of the page
+Quote Post
mattix19
post
Post #7





Grupa: Zarejestrowani
Postów: 32
Pomógł: 0
Dołączył: 11.07.2010

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


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...


--------------------
CI
Go to the top of the page
+Quote Post
Crozin
post
Post #8





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

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


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
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 Aktualny czas: 19.08.2025 - 06:55