Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Apua MySQL haun kanssa

Sivun loppuun

Nasu86 [21.07.2015 20:37:12]

#

Hei,
Tarvitsisin kokeneempien apua laajamittaisemman haun kanssa. Itse en tunnu etenevän tämän kanssa mihinkään ja nyt alkaa amatööriltä mielikuvitus jo loppumaan.

Olen tekemässä iltapuhteena tietokantasivustoa erään lajin harrastajille ja kasvattajille. Suurimmaksi kompastuskiveksi on muodostunut haku, jossa käyttäjien pitäisi pystyä hakemaan eläinten tietoja tietokannasta määrittelemiensä hakukriteereiden pohjalta.

Kriteereitä on tällä hetkellä nimi, sukupuoli, väri, kuvio, turkkimuunnos ja kasvattaja. Käyttäjän pitäisi voida hakea tietoja käyttäen joko yhtä tai useampaa kriteeriä. Lisäksi tulosten pitäisi natsata keskenään yhteen eli jos olen hakenut nimellä ja värillä, pitäisi ulos saada ainoastaan ne yksilöt joiden nimi ja väri täsmäävät keskenään. Ei siis kaikkia X-nimisiä ja Y-värisiä vaan ainoastaan ne joiden nimi on X ja väri Y.

Olen kokeillut kaikki perus AND/OR/LIKE syntaksit, niillä ei toimi niin kuin pitäisi. IF:llä ongelma helpottuu hieman mutta edelleen tavaraa tulee ulos liikaa (tai vaihtoehtoisesti ulos ei tule mitään...). Mitähän muuta olen jo ehtinyt säätämään...

Haluaisiko joku nero auttaa ja kertoa mikä olisi oikea tapa lähestyä tätä ? Mitä työkaluja tarvitsen, jotta voisin saada tämän toimimaan ? Esimerkit ovat luonnollisesti nekin tervetulleita mutten odota kenenkään kirjoittavan valmista koodia itselleni. Pienikin töytäisy oikeaan suuntaan voi auttaa paljon tässä suossa :)

Antti Laaksonen [21.07.2015 21:34:01]

#

Kuvauksesi perusteella AND kuulostaa kyllä toimivalta tavalta.

Esimerkiksi tämä etsii eläimet, joiden nimi on koira, väri on vaalea ja kasvattaja on Uolevi:

SELECT * FROM elaimet WHERE nimi='koira' AND vari='vaalea' AND kasvattaja='Uolevi'

Jos tämä ei ole tarkoittamasi asia, niin selventäisitkö vielä?

Nasu86 [21.07.2015 22:06:22]

#

Kiitos Antti vastauksestasi.

Olen kokeillut ANDiä mutta sillä en saa yhtään tulosta ulos ellen ole täyttänyt kaikkia hakukriteereitä.
Idea on kuitenkin se että käyttäjä voi hakea haluamallaan kombolla tietoja tietokannasta ja kriteerit voivat vaihdella yhden ja kuuden vaihtoehdon välillä (ja mikään näistä ei ole pakollinen).
Esimerkkejä (koska tätä on hankala selittää) hakukriteereistä:
- pelkkä nimi
- sukupuoli ja väri
- väri ja kasvattaja
- pelkkä kasvattaja jne....

Mietin pitäisikö IF:llä ensin tarkistaa onko formista tullut tietoa muuttujaan (eli hakukenttä täytetty) ja jos on, hakea sitten AND:llä tieto tietokannasta ?

Antti Laaksonen [22.07.2015 00:16:14]

#

OK, nyt ymmärrän asian paremmin. Ideasi on hyvä: voit tarkistaa PHP:ssä, mitkä kentät on annettu, ja muodostaa niistä sitten kyselyn.

Koodi voisi olla seuraavan tyylinen:

$osat = array();
$tiedot = array();
if ($_POST["nimi"] <> "") {
    $osat[] = "nimi = ?";
    $tiedot[] = $_POST["nimi"];
}
if ($_POST["sukupuoli"] <> "") {
    $osat[] = "sukupuoli = ?";
    $tiedot[] = $_POST["sukupuoli"];
}
// jne. muut kentät
$sql = "SELECT * FROM elaimet WHERE " . implode(" AND ", $osat);
$kysely = $yhteys->prepare($sql);
$kysely->execute($tiedot);

Metabolix [22.07.2015 15:12:33]

#

Kyselyn saa toimimaan oikein funktioilla IFNULL ja NULLIF. Ratkaisu riippuu hieman siitä, missä voi olla NULL ja missä tyhjä merkkijono ja miten ne halutaan käsitellä.

Eräs mahdollinen tapa sarakkeen vertailuun on tämä:

-- Tarkistus a = 'apina' hienommin:
IFNULL(IFNULL(a, '') = NULLIF('apina', ''), 1)

Kyselyn erikoiset kohdat oikealta vasemmalle:
NULLIF: Jos hakusana (yllä 'apina') on tyhjä teksti, tehdään siitä NULL.
IFNULL: Jos sarake (yllä a) on NULL, tehdään siitä tyhjä teksti.
IFNULL: Jos vertailun tulos on NULL, annetaan tulokseksi 1 eli tosi. (Vertailun tulos on NULL silloin, kun toinen vertailtavista on NULL, eli tässä tapauksessa silloin, kun hakusana on tyhjä.)

Tällä tavalla siis tyhjä hakusana tuottaa osuman. Muut hakusanat toimivat vertailussa aivan normaalisti. Eri sarakkeiden vertailut voi yhdistää ANDilla, kuten yleensäkin.

Samaan tulokseen pääsee tietenkin myös tavallisella IF-kutsulla, mutta silloin joutuu syöttämään saman hakusanan kyselyyn useampana kappaleena. Edellä kuvaamani kyselyn etu on siis se, että hakusana tulee vain yhteen kohtaan, kuten tavallisessakin vertailussa.

LIKE-tyyppisen haun voi tehdä INSTR-funktiolla. Kysymysmerkkejä ei tietenkään voi laittaa lainausmerkkeihin, joten LIKE "%?%" ei toimi, vaan tarvitaan INSTR(sarake,sana)>0. Tällainen kysely toimii, vaikka hakusana olisi tyhjä.

Nasu86 [24.07.2015 21:12:58]

#

Kiitos neuvoista!

Mitähän alla oleva errori tarkoittaa ja onko hyviä ideoita millä siitä pääsee eroon ?

Fatal error:
Uncaught exception 'PDOException' with message 'SQLSTATE[42000]:
Syntax error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1' in /home/u428947856/public_html/haku.php:221 Stack trace: #0 /home/u428947856/public_html/haku.php(221): PDOStatement->execute(Array) #1 {main} thrown in /home/u428947856/public_html/haku.php on line 221

Metabolix [24.07.2015 21:16:20]

#

Ilmoituksessa lukee, mistä on kyse: ”You have an error in your SQL syntax”, SQL-kyselyssäsi on syntaksivirhe. Sijainti ”near ''” tarkoittaa käytännössä, että virhe on kyselyn lopussa, koska muuten heittomerkkien välissä lukisi jokin aikaisempi kyselyn kohta.

Jos yritit käyttää Antin koodia, ehkä kävi niin, että et syöttänyt yhtään hakusanaa ja kyselystä tuli ”SELECT * FROM elaimet WHERE” ilman ehtoja.

Nasu86 [24.07.2015 22:19:11]

#

Kiitos teille, haku toimii nyt lähes oikein. Ainoastaan nimellä haku ei toimi ja ääkköset tulostuu kysymysmerkkeinä mutta muuten haku antaa oikeat tulokset ulos.

Metabolix [24.07.2015 23:02:02]

#

Nasu86 kirjoitti:

Ainoastaan nimellä haku ei toimi

Sitten koodissasi (tai tietokannassasi) on varmaan jotain vikaa sen kohdalla. Jos sarake on samanlainen kuin muut sarakkeet, hakukin toimii ihan samalla tavalla.

Nasu86 kirjoitti:

ääkköset tulostuu kysymysmerkkeinä

Selvästi jossain kohti käytät väärää merkistökoodausta. Kannattaa tehdä sivut kokonaan UTF-8-merkistökoodausta käyttäen; tähän on neuvoja oppaassa.

Nasu86 [25.07.2015 18:32:36]

#

Kiiitos jälleen kerran, molemmat ongelmat ratkesivat.

Sen verran voisin vielä teidän ammattitaitoanne lainata että olisiko hyviä neuvoja miten saan tehtyä nimistä linkit eläinten omille sivuille ?

Tällä olen kokeillut viimeiseksi mutta tämä ei toimi. Linkki heittää kyllä oikeaan kansioon mutta 'nimi' ei ohjaa oikealle sivulle.

<td><a href="elaimet/$rivi['nimi]"><?php echo $rivi['nimi']; ?></a></td>

ErroR++ [25.07.2015 18:42:22]

#

Eikös tuo $rivi['nimi'] pitäisi olla <?php-tagin sisällä, koska muuten PHP ei prosessoi sitä? Eli

<?php
echo "<td><a href='elaimet/" . $rivi['nimi'] . "'>" . $rivi['nimi'] . "</a></td>";
?>

tai jotain vastaavaa.

Nasu86 [25.07.2015 18:56:58]

#

No sillähän se ratkesi, tattista! :)
Nyt ei muuta kuin pää uuteen soppaan ja menoksi...

The Alchemist [27.07.2015 12:04:41]

#

ErroR++ kirjoitti:

Eikös tuo $rivi['nimi'] pitäisi olla <?php-tagin sisällä, koska muuten PHP ei prosessoi sitä? Eli

<?php
echo "<td><a href='elaimet/" . $rivi['nimi'] . "'>" . $rivi['nimi'] . "</a></td>";
?>

tai jotain vastaavaa.

Älä roskaa. Lisäksi olisi aika tärkeää enkoodata url ja nimi käyttäen htmlspecialchars-funktiota (h).

<td><a href="<?= h($row['url']) ?>"><?= h($row['name']) ?></a></td>

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta