Jälleen kerran..
Alla oleva mysql-komennon pätkä bugaa jotenkin, mutta miten?
$query = "SELECT id, nick, rek_aika FROM users WHERE id LIKE '".$_POST['s_id']."' OR nick LIKE '".$_POST['s_user']."' AND piilota_nick = '0'";
MySQL-yhteydet on kunnossa, sekä tämän kyselyn palauttama data käsitellään oikein, testattu on.
LIKE:n kanssahan käytetään prosenttimerkkejä. Olisiko apua?
Et sitten viittinyt laittaa sitä virheilmoitusta? Ainakin numeeristen kenttien kanssa työskennellessä, voi hipsut heittää suohon. Toiseksi käyttäjän lähettämät arvot pitää tarkastaa, eikä pistää suoraan sql-lauseeseen. Niin ja tosiaan tuo LIKE-vertailu on hieman turha tuossa, jos et käytä prosenttimerkkejä. Ja vielä turhemmaksi se muuttuu jos käytät prosenttimerkkejä. Tarkoitan lähinnä tuon id:n hakemista LIKE:llä.
Zori, tuli vähän negatiivinen viesti :)
Jos ei LIKE-verailuun voi lisätä villiä korttia (%) niin sitten vaihda tuon LIKE:n tilalle REGEXP.
Hieman höpöhöpöä tullut, LIKEn kanssa ei ole pakko käyttää prosentteja, ja LIKE on hyödyllinen kun sitä käytetään alfanumeerisessa kentässä joka on asetettu käyttäen BINARYa. Tällöin LIKE löytää "JaSkA" haulla "jaska", "Jaska", "JaskA" ja niin edelleen.
Mutta tosiaan, numeerisissa kentissä siitä ei oikein ole hyötyä, mutta älä luovu hipsuista. Mieluummin hipsutettu, hieman huonommin tarkastettu numero kuin hipsuttamaton, huonosti tarkastettu "ehkä" numero.
Mitä tulee kyselyn bugaamiseen, auttaa ehdoissa sulut. Nythän kysely mätsää jos id on s_id TAI (nick = s_user JA piilota_nick = 0). Veikkaisin että tarkoitus olisi näyttää jos id TAI nick täsmää ja näiden lisäksi piilota_nick on nolla vai? Siitä vaan pähkäilemään sulkuja oikeisiin väleihin.
Jep, oikein leftover. Ja tosiaan hipsuja tulen käyttämään joka kohdassa, se on jo tapa.
Ihan omakohtaisella kokemuksella voin sanoa että nuumerisissa kentissä ei kannata hipsuja käyttää. Monessa tapauksessa kantaan tallennettaessa '30' menee kantaan muodossa 0, koska se tulkitaan tekstiksi, jota ei numeeriseen kenttään voi tallentaa.
leftover kirjoitti:
LIKE on hyödyllinen kun sitä käytetään alfanumeerisessa kentässä joka on asetettu käyttäen BINARYa.
Tämä oli minulle uutta tietoa. En ole ikinä tuollaista kenttää missään käyttänyt, joten olenkin aina ihmetellyt miten LIKE eroaa normaalista yhtäsuuruus (=) -vertailusta (pl. nuo Wild Cardit), sillä käsitteleehän normaali yhtäsuuruusvertailukin ainakin "normaalisti asetetuissa" (VAR)CHAR- ja TEXT-kentissä merkkijonot case insensistivenä. Voisitko vielä valaista ihan selko SQL-kielellä miten "asetan VARCHAR-kentän käyttäen BINARYa"? :)
Edit: Pikainen vilkaisu manuaaliin ja löysin kentän "VARBINARY". Se tekee kyllä kentästä CASE SENSITIVEN, mutta...
DROP TABLE IF EXISTS foo; CREATE TABLE foo( id INT auto_increment primary key, `data` VARBINARY(255) ); INSERT INTO foo (`data`) VALUES ('Kuukerin Nelli'); SELECT * FROM foo WHERE `data` = 'kuukerin nelli'; SELECT * FROM foo WHERE `data` LIKE 'kuukerin nelli';
Eipä palauta nuo koodit kannasta mitään. Sen sijaan jos vaihtaa
SELECT * FROM foo WHERE `data` LIKE 'Kuukerin Nelli'
niin palauttaa ihan oikein. Eli siis LIKE ei sittenkään tee hausta CASE-INSENSITIVEä? Vai onko tuo VARBINARY nyt kuitenkin eri kenttä kuin mitä tarkoitit?
No anyway, opinpa ainakin jotain uutta.
raezel kirjoitti:
Ihan omakohtaisella kokemuksella voin sanoa että nuumerisissa kentissä ei kannata hipsuja käyttää. Monessa tapauksessa kantaan tallennettaessa '30' menee kantaan muodossa 0, koska se tulkitaan tekstiksi, jota ei numeeriseen kenttään voi tallentaa.
Kyllä se '30' menee kantaan 30 mutta ' 30' menee kantaan nollana. Lisäksi se arvo pitää kuitenkin tarkastaa ennen kantaan junttaamista, joten miksi ei samoin tein tarkasta is_numeric joka mielestäni mussuttaa välilyönneistä?
ajv kirjoitti:
niin palauttaa ihan oikein. Eli siis LIKE ei sittenkään tee hausta CASE-INSENSITIVEä? Vai onko tuo VARBINARY nyt kuitenkin eri kenttä kuin mitä tarkoitit?
hmm, itse olen käyttänyt ja mitä ilmeisimmin manuaalistakin tonkinut tiedon mikä sanoo että TINYTEXT BINARY saadaan data ulos case-insesitivenä LIKEllä.
http://dev.mysql.com/doc/mysql/en/string-comparison-functions.html:
The following two statements illustrate that string comparisons are not case sensitive unless one of the operands is a binary string: mysql> SELECT 'abc' LIKE 'ABC'; -> 1 mysql> SELECT 'abc' LIKE BINARY 'ABC'; -> 0
Eli olen selkeästi sotkenut asioita pienessä sievässä mielessä. No, toimii se ainakin käänteisenä, eli eiBINARY kentissä ('abc' = 'ABC') = 0 mutta ('abc' LIKE 'ABC') = 1.
leftover kirjoitti:
eli eiBINARY kentissä ('abc' = 'ABC') = 0 mutta ('abc' LIKE 'ABC') = 1.
Ei... Nuo kummatkin palauttavat kyllä ykkösen, silloin kun kyseessä on tavallinen ei BINARY-muotoinen tekstikenttä, eikö?
Noni, 2,5 kupillista aamukahvia auttoi. Pienet testit
SELECT 'abc' = 'ABC', 'abc' = BINARY('ABC'), 'abc' LIKE 'ABC', 'abc' LIKE BINARY('ABC')
ja tulos
1 0 1 0
Eli näinhän se käyttäytyy kuten ajv sanoi. Nöyrryn kohtalooni ja poistun takavasemmalle lukemaan MySQL:n manuaalia. Onneksi en ole binaryn ystävä, tiedän että vikaa ei ole kuin yhdessä kyselyssä, luojalle kiitos :/
Heh... :)
Eli lopullisena johtopäätöksenä kaikista testeistä voidaan pitää sitä tosiasiaa, että LIKE-vertailu ei eroa yhtäsuuruus-vertailusta mitenkään muuten, kuin että LIKE:n kanssa voidaan käyttää noita Wild Cardeja (% ja _).
Nyt menee jo turhaksi optimoinniksi, mutta jos ei noita Wild Cardeja aio käyttää, voi kyselyn tehdä normaalilla yhtäsuuruusvertailulla, jolloin voisin kuvitella haun olevan aavistuksen verran nopeampi, koska tällöin tietokannan ei tarvitse tarkastaa sisältääko hakusana noita Wild Cardeja (Tätä ajoin takaa ensimmäisessä viestissänikin, kun sanoin LIKE-vertailun olevan hieman turha.).
Tuo binary-kenttä sopii minusta erittäin hyvin esim. käyttäjätunnuksen ja salasanan säilyttämiseen. Tällä hetkellä oma kirjautumis-koodini päästää sisään ajv:n myös käyttäjätunnuksella AJV.
Aihe on jo aika vanha, joten et voi enää vastata siihen.