Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Hämminkiä Mysql-lauseessa

Sivun loppuun

pistemies [31.05.2012 17:31:27]

#

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ä?

Grez [31.05.2012 18:06:00]

#

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

pistemies [31.05.2012 20:39:05]

#

Grez kirjoitti:

Tai vielä parempi: käytä parametrisoituja kyselyitä.

Miten noita toteutetaan mysql-lauseessa?

pistemies [01.06.2012 09:43:51]

#

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.

Grez [01.06.2012 09:46:36]

#

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.

qeijo [01.06.2012 11:14:08]

#

Poista luvuista tilapäisesti pisteet (ensimmäistä pistettä lukuunottomatta) sekä PHP että Myslin puolella..

Edit:
Toimii tilanteissa jossa versionumerointi sen sallii.

Grez [01.06.2012 11:27:48]

#

Miksi?

(En keksi mitään tilannetta jossa pisteiden poistamisella saavutettaisiin jokin hyöty)

qeijo [01.06.2012 12:20:55]

#

Grez kirjoitti:

Miksi?

(En keksi mitään tilannetta jossa pisteiden poistamisella saavutettaisiin jokin hyöty)

Sillä olisi (myös) saavutettu oikea ratkaisu.

Lebe80 [01.06.2012 12:31:15]

#

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

ZeroGravity [01.06.2012 12:34:32]

#

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.

Lebe80 [01.06.2012 13:13:39]

#

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)

Grez [01.06.2012 13:27:36]

#

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.

pistemies [01.06.2012 13:28:50]

#

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

Grez [01.06.2012 13:31:56]

#

pistemies kirjoitti:

jos olisi käytössä PDO, joutuisi keksimään toisenlaisen

Siis minkä ratkaisun nyt sitten kehitit joka ei onnistuisi PDO:lla?

pistemies [01.06.2012 13:35:57]

#

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.

Lebe80 [01.06.2012 13:40:06]

#

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ä?

pistemies [01.06.2012 13:48:34]

#

Lebe80 kirjoitti:

Tarviiko pdo:ssa eskapoida itse stringejä?

Eipä kai kovin kaksisesti :)

Lebe80 [01.06.2012 15:42:37]

#

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();

The Alchemist [01.06.2012 15:53:25]

#

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.


Sivun alkuun

Vastaus

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

Tietoa sivustosta