• User

    Problema con motore di ricerca like php mysql e campo NULL

    Ciao ragazzi, come da titolo ho un motore di ricerca interno che non funziona come dovrebbe.
    Ho un campo "lingua" impostato come "NULL" e una select con tre scelte:
    -* tutte*

    • italiano
      -* inglese*
      quando effettuo la ricerca selezionando "italiano" o "inglese" funziona, ma quando si seleziona "tutte", mi da 0 (zero) record

    Il campo select e' il seguente:
    <select name="lingua" id="lingua">
    <option value="">tutte</option>
    <option value="italiano"> italiano </option>
    <option value="inglese"> inglese </option>
    </select>

    premesso che il campo "NULL" non e' un campo vuoto ma "inesistente" ho scritto il seguente codice:
    ?SELECT * FROM nometabella WHERE ((lingua LIKE '%s') OR ((lingua <> '') AND (lingua IS NULL)))?
    ma non funziona

    Come faccio a far visualizzare tutti i record (compresi i "NULL") quando seleziono "tutte"??


  • User Attivo

    Prova con SQLinjection (almeno credo che anche questo possa essere considerato tale):
    <option value="italiano OR lingua = 'inglese'">Tutte</option>

    La query sarà (immagino):
    SELECT * FROM nometabella WHERE lingua = '".$_POST['lingua']."'


  • User

    ciao meis, e grazie per la risposta, ma non funziona, mi da come risultato 0 (zero).
    Posso convertire il campo NULL in NOT NULL con valore predefinito vuoto?
    Perche' il problema e' il campo NULL, infatti se tutti i record contengono dati (italiano o inglese), tutto funziona regolarmente, se invece ci sono anche record con "valore" NULL, non funziona piu' bene


  • User

    if ($_POST['lingua']==tutte) sql=SELECT lingua FROM nometabella WHERE ((lingua LIKE '%s')
    sql_risultato=@mysql_query($sql,$this->DB_conn) or die (mysql_error());


  • User

    ciao marco1983, il codice non funziona. L'idea dovrebbe essere questa: se seleziono "tutte", stampami tutti i record che hanno un valore (italiano e inglese) e quelli senza un valore (campi NULL).
    Ho provato con questo:
    SELECT * FROM nometabella WHERE ((lingua LIKE '%s') OR ((lingua <> '') AND (lingua IS NULL)))
    selezionando "tutte", mi da come risultato 0, se seleziono o italiano o inglese, funziona

    con questo codice:
    SELECT * FROM nometabella WHERE ((lingua LIKE '%%%s%%') OR ((lingua <> '') AND (lingua IS NULL)))
    selezionando "tutte", mi stampa tutti i record a parte i campi "NULL", se seleziono o italiano o inglese, funziona.

    Per semplificare... nel database ci sono 5 record con valore "italiano", 5 record con valore "inglese" e 5 record senza un valore, perche i campi sono "NULL" ;
    con quest'ultimo codice mi stampa solo 10 risultati (5 italiano + 5 inglese) invece di 15 (5 italiano + 5 inglese + campi NULL)


  • User Attivo

    Se ometti il where? solo SELECT * FROM nometabella


  • User

    solo con il SELECT mi mostra TUTTI i record compresi i NULL


  • User Attivo

    Non era questo quello che stavi cercando di fare? Devo ammettere che sono un po' confuso...


  • User

    si, era quello che volevo, ma come faccio a filtrare i dati?
    Cerco di semplificare e mi spiego meglio:
    Ho un form per inserire dati in un db; il form ha due campi select, il campo "sesso"(uomo, donna) e "lingua"(italiano, inglese), entrambi sono impostati come "NULL". I campi non sono obbligatori quindi capita che il campo "lingua", non venga compilato, in quel caso rimane senza valore perche' e' NULL.

    Per semplificare...

    sesso | lingua
    ----------+----------
    uomo | italiano
    donna | italiano
    uomo | NULL
    donna | inglese

    Veniamo al problema.
    Una volta inseriti, devo filtrare i risultati con un form di ricerca multipla, anche questo contiene due campi select: "sesso"(tutti, uomo, donna) e "lingua"(tutte, italiano, inglese). Per il campo "sesso" non c'e' problema. Per il campo lingua, se seleziono "tutte" mi stampa solo 3 record, perche' 1 campo e' NULL e non sembra considerarlo. Cosi' mi falsa tutte le ricerche. Infatti, se volessi sapere quanti "uomini" ci sono, selezionando lingua su "tutte", mi troverebbe 1 risultato, perche' l'altro e' NULL.
    In pratica, vorrei sapere quale codice devo utilizzare per sapere quanti "uomini" ci sono impostando il campo "lingua" su "tutte".

    SELECT * FROM nometabella WHERE sesso LIKE '%%%s%%' AND ((lingua LIKE '%%%s%%') OR ((lingua <> '') AND (lingua IS NULL)))
    selezionando "tutte" nel campo lingua, mi stampa tutti i record a parte i campi "NULL", se seleziono o italiano o inglese, funziona.


  • User Attivo

    Uhm... ora ho capito... vediamo un po'...

    [PHP]
    if($_POST['lingua'] != NULL)
    {
    $query = "SELECT * FROM nometabella WHERE sesso LIKE '%%%s%%' AND ((lingua LIKE '%%%s%%')";
    }
    else
    {
    $query = "SELECT * FROM nometabella WHERE sesso LIKE '%%%s%%'";
    }
    [/PHP]

    Questa è l'unica soluzione che mi viene in mente, ma sembra che tu voglia una query che funzioni in ogni caso, senza bisogno dell'if, vero? in questo caso non so come aiutarti


  • User

    da phpmyadmin in struttura deseleziona predefinito "NULL"...
    nei campi select se l'utente non segna la lingua quindi campo vuoto fai scrivere nel db "Non segnalato" (o quel che vuoi)..
    il campo null essendo un campo senza dato non viene letto nell ricerca db.. perchè non contiente nulla...
    quando poi stampi i record oltre a "italiano" o "inglese" apparirà "non segnalato" oppure tramite una condizione non fai comparire nulla...


  • User

    ciao marco1983, avevo gia' pensato a questa soluzione, era la mia "ultima spiaggia".
    Dal phpmyadmin e' possibile attribuire al campo NULL un valore di default, ad esempio "vuoto"? In questo caso se l'utente non compilasse la lingua, nel db rimarrebbe il valore di default "vuoto", e' possibile?


  • User

    ciao ragazzi, alla fine ho sostituito tutti i campi NULL con "-" e funziona tutto alla perfezione.
    Ora pero' dovrei filtrare i dati in base all'eta', nel senso:
    stampami tutti gli utenti con eta' compresa da 18 a 30;
    ho provato con BETWEEN:

    SELECT * FROM utenti WHERE eta BETWEEN 18 AND 30

    e funziona,
    ma come faccio a renderlo "dinamico", in modo che prelevi l'eta' da una select tipo la seguente?

    <select name="eta" id="eta">
    <option value="da 18 a 30">da 18 a 30</option>
    <option value="da 31 a 40">da 31 a 40</option>
    </select>


  • User Attivo

    i value dovranno essere
    "18 AND 30"
    "31 AND 40"

    SELECT * FROM utenti WHERE eta BETWEEN ".$_POST['eta']


  • User

    Ciao meis, ho provato, ma mi da errore "You have an error in your SQL syntax; check the manual…"
    Questo e' il codice:

    SELECT * FROM utenti WHERE eta BETWEEN ".$_POST['eta']." AND lingua LIKE '%%%s%%' …

    <select name="eta" id="eta">
    <option value="da 18 a 30">da 18 a 30</option>
    <option value="da 31 a 40">da 31 a 40</option>
    </select>

    Ho modificato il codice in modo che la ricerca avvenga con 2 select, lasciando più' libertà' all'utente:

    SELECT * FROM utenti WHERE eta ".$_POST['eta']." ".$_POST['eta2']." AND lingua LIKE '%%%s%%' …

    <select name="eta" id="eta">
    <option value="BETWEEN 18 ">18</option>
    <option value="BETWEEN 19">19</option>
    <option value="BETWEEN 20 ">20</option>
    ...
    </select>

    <select name="eta2" id="eta2">
    <option value="BETWEEN 18 ">18</option>
    <option value="BETWEEN 19">19</option>
    <option value="BETWEEN 20 ">20</option>
    ...
    </select>

    Così' funziona, ma e' corretto?

    Per una maggior pulizia del codice vorrei utilizzare i campi di testo al posto delle select, ed ho utilizzato il seguente codice:

    SELECT * FROM utenti WHERE eta ".$_POST['eta']." ".$_POST['eta2']." ".$_POST['eta3']." ".$_POST['eta4']." AND lingua LIKE '%%%s%%' …

    <input name="eta" type="hidden" id="eta" value="BETWEEN" />
    <input name="eta2" type="text" id="eta2" />
    <input name="eta3" type="hidden" id="eta3" value="AND" />
    <input name="eta4" type="text" id="eta4" />

    così' l'utente può' scrivere direttamente l'eta' senza "cercarla" nella select.
    Funziona, ma se non compilo i campi, mi da' errore "You have an error in your SQL syntax; check the manual…"
    Come posso fare?


  • User Attivo

    eta e eta3 puoi inserirli direttamente nella query, non serve farci degli input type=hidden.

    per risolvere l'errore puoi controllarlo: se eta2 o eta4 sono = a NULL generi un alert e torni al formulario... o comunque una soluzione simile


  • User

    i campi eta' hanno tutti un valore, l'ho meso come campo obbligatorio.
    Ho scritto cosi':
    SELECT * FROM utenti WHERE eta BETWEEN ".$_POST['eta']." AND ".$_POST['eta3']." AND lingua LIKE '%%%s%%' …
    mi da sempre errore, penso ci siano problemi tra l'AND del BETWEEN e l'AND successivo, quello della lingua.
    Ho provato anche cosi':
    SELECT * FROM utenti WHERE eta BETWEEN (".$_POST['eta']." AND ".$_POST['eta3'].") AND lingua LIKE '%%%s%%' …
    per isolare l'AND del BETWEEN dall'AND successivo, ma niente


  • User Attivo

    Con il between ci dovrebbero essere le virgolette, prova con:
    SELECT * FROM utenti WHERE eta BETWEEN ('".$_POST['eta']."' AND '".$_POST['eta3']."') AND lingua LIKE '%%%s%%'


  • User

    con questo:
    SELECT * FROM utenti WHERE eta BETWEEN ('".$_POST['eta']."' AND '".$_POST['eta3']."') AND lingua LIKE '%%%s%%'
    non funziona.
    Con questo:
    SELECT * FROM utenti WHERE eta BETWEEN ('".$_POST['eta']."') AND ('".$_POST['eta3']."') AND lingua LIKE '%%%s%%'
    funziona parzialmente, ma se non compilo i campi, mi da 0(zero), come risultato;
    quindi se voglio estrarre tutti gli utenti "italiani", tralasciando i campi eta', non mi estrae niente


  • User

    Se vuoi tutti gli italiani
    o inserisci nei campi età da 0 a 150 (cerca tutti gli italiani di età compresa fra 0 e 150)
    oppure devi fare una condizione che controlli i campi età lanciando 2 query differenziate a seconda del risultato (se età è stato tralasciato cerca tutti gli italiani altrimenti cerca gli italiani con età compresa fra eta ed eta3)
    oppure devi fare 2 condizioni prima di lanciare la tua query impostando dei valori predefiniti ai campi età nel caso questi vengano omessi (se non è stato inserito eta allora eta=0; se non è stato inserito eta3 allora eta3=150, cerca gli italiani con età compresa fra eta ed eta3)