IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Mezi 13:00 až cca 16:00 proběhne odstávka sítě z důvodu aktualizace. Web bude po celou dobu nedostupný.

Diskuze: Chyba pri výbere z databazy pomocou operatoru IN

Aktivity
Avatar
mayo505
Tvůrce
Avatar
mayo505:1.2.2014 22:31

Zdravím,
mám problém pri výbere položiek z databázy pomocou operátoru IN.
Kód vyzerá takto:

$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN (?)");
$navrat->execute(array($produkty));
return $navrat->fetchAll();

kde $produkty by mal byť reťazec obsahujúci id viacerých produktov vo formáte napríklad "1,3,5"

Problém je však v tom, že aj keď ten reťazec obsahuje viacej čísel, stále vráti len jeden záznam, hneď ten prvý

V čom môže byť chyba?

Tento kód funguje bezchybne

$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN (" . $produkty . ")");
$navrat->execute();
return $navrat->fetchAll();
Editováno 1.2.2014 22:34
 
Odpovědět
1.2.2014 22:31
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na mayo505
David Hartinger:2.2.2014 14:09

Metoda execute() bohužel nebude umět vložit přímo array. Musíš to udělat přes funkci implode a ty idčka si oddělit čárkou:

$this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN (" . implode(',', $poleIdcek) . ")");

Musíš také počítat s SQL injection, takže si ty hodnoty prohnat PDO fcí quote.

Editováno 2.2.2014 14:10
Nahoru Odpovědět
2.2.2014 14:09
New kid back on the block with a R.I.P
Avatar
mayo505
Tvůrce
Avatar
mayo505:2.2.2014 14:52

ale premenná $produkty nieje array ale reťazec obsahujúci id produktov oddelené čiarkami (vlastne to isté čo urobí implode), vadí to aj tak? Keď som ho echoval tak vyzeral presne ako má.
To array vo funkcii execute mám preto, lebo tá funkcia očakáva pole prvkov ktoré potom nahradia tie otázniky ... aspoň tak som to chápal ... myslel som, že dotaz sa vykoná až potom

 
Nahoru Odpovědět
2.2.2014 14:52
Avatar
mayo505
Tvůrce
Avatar
mayo505:2.2.2014 15:17

skúsil som to aj s tou funkciou quote asi takto

$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN (". $this->spojenie->quote($produkty) .")");

lenže tá funkcia pridá na začiatok aj na koniec úvodzovky takže ako keby ten dotaz bol takýto

$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN ('". $produkty "')");

alebo

$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN ('1,2,3')");

všetky (aj to s tým $produkty v execute) urobia presne to isté, vyberú z databázy len prvú položku.

Tie úvodzovky (či apostrofy či čo to je) by tam nemali byť

Editováno 2.2.2014 15:19
 
Nahoru Odpovědět
2.2.2014 15:17
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na mayo505
David Hartinger:3.2.2014 17:30

Nevím, kde tu proměnnou bereš, ale jak jsem psal, zaprvé ti nepůjde vložit přes execute a zadruhé je to dost nebezpečné kvůli SQL injection. Proto se to dělá tak, že si ten řetězec vyrobíš sám a ošetříš si ho sám.

Nahoru Odpovědět
3.2.2014 17:30
New kid back on the block with a R.I.P
Avatar
mayo505
Tvůrce
Avatar
Odpovídá na David Hartinger
mayo505:3.2.2014 18:36

No to kde ju beriem by sa podľa mňa nemalo brať do úvahy, hlavne, že je v správnom tvare. Napokon som to vyriešil takto

$veci = $this->spojenie->quote($produkty);
$veci[0] = "";
$veci[strlen($veci) - 1] = "";
$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN (". $veci .")");
$navrat->execute();

quote je kvôli sql injection, len pridá tam tie apostrofy, dopredu a dozadu tak som ich odstranil

Editováno 3.2.2014 18:36
 
Nahoru Odpovědět
3.2.2014 18:36
Avatar
mayo505
Tvůrce
Avatar
mayo505:3.2.2014 19:07

Tak napokon s pre mňa nepochopiteľných dôvodov nefungoval ani ten kód hore a musel som to zmeniť na toto

$veci = $this->spojenie->quote($produkty);
$veci = substr($veci, 1);  // odstráni prvý apostrof
$veci = substr($veci, 0, strlen($veci) - 1);  // odstráni posledný apostrof
$navrat = $this->spojenie->prepare("SELECT * FROM produkt WHERE produkt_id IN ($veci)");
$navrat->execute();
 
Nahoru Odpovědět
3.2.2014 19:07
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.