Siis tässä:
WHERE (a.parent_id = '" . (int)$parent_id . "' AND ad.language_id = '1') AND a.status = '1' AND ad.version = 'general' OR (a.parent_id = '" . (int)$parent_id . "' AND ad.language_id = '1') AND a.status = '1' AND ad.version = '" . $versio ."' OR (a.parent_id = '" . (int)$parent_id . "' AND ad.language_id = '1') AND a.status = '1' AND (ad.version < '" .(int)$versio . "' AND ad.version <> '1.4.9') ORDER BY a.sort_order, LCASE(ad.name)"
En oikein saa tuota viimeistä ehtoa toteutumaan. Minulla tuossa muuttuja $versio on 1.5.2, tuossa kohtaa taulussa ad.version on 1.5.1. Miten tuo tarkalleen kuuluisi mennä?
Et voi castata muuttujaa 1.5.2 intiksi, koska sehän ei selvästikään ole numero ja vielä vähemmän kokonaisluku.
laita (int)$versio tilalle mysql_real_escape_string($versio)
Tai vielä parempi: käytä parametrisoituja kyselyitä.
Grez kirjoitti:
Tai vielä parempi: käytä parametrisoituja kyselyitä.
Miten noita toteutetaan mysql-lauseessa?
Juu, kiitoksia vaan. Kyllä mie sain sen tuolla "vanhanaikaisella" toimimaan. Sattumalta, koska tämä ohjelma, jota teen, ei käytä PDO:ta.
Olisi vaan ollut kiva, jos tuohon olisi löytynyt jokin php:n matemaattinen termi. Matikassa kait luvulla 1.5.2 on jokin tietty luku-ryhmä, johon se kuuluu.
En ymmärrä mitä iloa sinulle olisi ollut, vaikka PHP:ssä olisikin tuki moniosaiselle luvulle.. vertailu kuitenkin tapahtuu MySQL:n puolella.
Jos PHP:ssa haluaisi tehdä vertailuja, niin tuolle voisi tehdä oman luokan, joka sisältäisi vertailuoperaatiot. Käytännössä siis jaetaan pisteiden kohdilta taulukkoon ja vertaillaan sitten osa kerrallaan alusta alkaen kunnes löytyy ero.
Matemaattisesti en äkkiseltään keksi tuolle mitään järkevää oliota. Toki sen voisi laittaa vaikkapa vektoriksi, mutta esimerkiksi vektorin itseisarvo ei olisi mitenkään järkevä tuollaiselle.
Poista luvuista tilapäisesti pisteet (ensimmäistä pistettä lukuunottomatta) sekä PHP että Myslin puolella..
Edit:
Toimii tilanteissa jossa versionumerointi sen sallii.
Miksi?
(En keksi mitään tilannetta jossa pisteiden poistamisella saavutettaisiin jokin hyöty)
Grez kirjoitti:
Miksi?
(En keksi mitään tilannetta jossa pisteiden poistamisella saavutettaisiin jokin hyöty)
Sillä olisi (myös) saavutettu oikea ratkaisu.
Toisaalta qeijon homma kosahtaa heti kun versiossa on yli kympin arvoja (sikäli mikäli edes ymmärsin pisteiden poistosta):
1.4.9 -> 1.49
1.4.10 -> 1.410
1.4.9 -> 1.49
1.10.1 -> 1.101
Pitää ottaa huomioon, että joskus versionumero voi myös olla 1.11.3 jolloin pisteiden poistaminen tuottaisi väärän tuloksen, jos vertaisi vaikka 2.0.1 versioon.
Ehkä tuossa pitäisi tehdä joku kantafunktio/-proceduuri, joka tekisi saman kuin https://www.php.net/manual/en/function.version-compare.php, mutta menee aika monimutkaiseksi.
qeijo kirjoitti:
Poista luvuista tilapäisesti pisteet (ensimmäistä pistettä lukuunottomatta) sekä PHP että Myslin puolella..
ZeroGravity kirjoitti:
Pitää ottaa huomioon, että joskus versionumero voi myös olla 1.11.3 jolloin pisteiden poistaminen tuottaisi väärän tuloksen, jos vertaisi vaikka 2.0.1 versioon.
Paitsi, ettei se juuri noihin mainitsemiisi versioihin antaisi väärää tulosta. (1.113 < 2.01)
qeijo kirjoitti:
Sillä olisi (myös) saavutettu oikea ratkaisu.
Ei pidä paikkaansa.
Pisteen poistaminen ei hirveästi vaikuta lopputulokseen
"1.4.9" > "1.4.10" ja ihan yhtä lailla
"1.49" > "1.410"
Samoin
"10.3.57" < "9.8.2" ja ihan yhtä lailla
"10.357" < "9.82"
Toki sillä pisteen poistolla voidaan saada erojakin, eri asia sitten mennäänkö parempaan vai huonompaan suuntaan:
"1.1.7" < "1.13.3"
"1.17" > "1.133"
Jos olisit sanonut, että poistetaan pisteet ja muutetaan luvuiksi, niin sittenhän tuossa olisi tuon "major"-version osalta ollut sentään jotain hyötyä. Tämäkin on kuitenkin paska(TM) ratkaisu, kun sellaisiakin ratkaisuja on jotka toimii aina oikein.
Kyllä tuo riittää mulle tässä tilanteessa hyvin. Tuli vaan mieleen, että jos ohjelmassa johon tätä teen, olisi käytössä PDO, joutuisi keksimään toisenlaisen, jonkin oman systeemin (vai oliko mysql-lauseissa jokin oma sql-funktio, jolla poistaa sarakkeesta pisteet vertailun ajaksi , en muista).
pistemies kirjoitti:
jos olisi käytössä PDO, joutuisi keksimään toisenlaisen
Siis minkä ratkaisun nyt sitten kehitit joka ei onnistuisi PDO:lla?
Grez kirjoitti:
pistemies kirjoitti:
jos olisi käytössä PDO, joutuisi keksimään toisenlaisen
Siis minkä ratkaisun nyt sitten kehitit joka ei onnistuisi PDO:lla?
Funktio mysql_real_escape_string ei toimi PDO:ssa, ei ainakaan minulla.
pistemies kirjoitti:
Grez kirjoitti:
pistemies kirjoitti:
jos olisi käytössä PDO, joutuisi keksimään toisenlaisen
Siis minkä ratkaisun nyt sitten kehitit joka ei onnistuisi PDO:lla?
Funktio mysql_real_escape_string ei toimi PDO:ssa, ei ainakaan minulla.
Tarviiko pdo:ssa eskapoida itse stringejä?
Lebe80 kirjoitti:
Tarviiko pdo:ssa eskapoida itse stringejä?
Eipä kai kovin kaksisesti :)
Ainakin oman käsityksen mukaan se tekee kaikki nuo juuri automaattisesti itse, kun ei vaan tunge niitä arvoja suoraan siihen kyselyyn, vaan antaa ne erillisinä parametreinä:
$statement = $db->prepare('SELECT * FROM someTable WHERE something = :comparison'); $statement->execute(array(':comparison' => $comparison)); $results = $statement->fetchAll();
Lebe80 kirjoitti:
Ainakin oman käsityksen mukaan se tekee kaikki nuo juuri automaattisesti itse, kun ei vaan tunge niitä arvoja suoraan siihen kyselyyn, vaan antaa ne erillisinä parametreinä:
$statement = $db->prepare('SELECT * FROM someTable WHERE something = :comparison'); $statement->execute(array(':comparison' => $comparison)); $results = $statement->fetchAll();
Se ei tee eskapointia ollenkaan, koska sitä ei tarvita. Parametrisoidut kyselyt (alias prepared statements) ovat ihan oma juttunsa.
Mysql_real_escape_stringin pelitys ei riipu mitenkään siitä, onko käytössä PDO tai jokin muu(kin) rajapinta tietokannan käpistelyyn. Tarvitset ainoastaan mysql_connect()-funktiolla avatun kahvan tietokantaan.
Mikäli halutaan istuttaa PDO vanhan koodin kylkeen, niin helpoiten mysql_real_escape_stringin pitää toiminnassa asettamalla ajonaikaisesti ini_set()-funktiolla asetukset mysql.default_user ja mysql.default_password. Tällöin mysql_real_escape_string() osaa avata kahvan taustalla aina tarvittaessa.
Tosi juttu on taas se, ettei PDO:n kanssa pitäisi käyttää mysql_real_escape_stringiä ollenkaan. Yleensäkään mitään mysql_-alkuista ei pitäisi käyttää lainkaan. PDO:ssa on oma funktionsa, PDO::escape(), jos tarvitsee istuttaa arvoja kyselyihin käsin. Sen toiminta on kuitenkin aavistuksen erilainen (järkevämpi) kuin mysql_real_escape_stringin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.