2009-12-07 4 views
0

J'ai une simple requête SQL,Méthode pour faire correspondre une chaîne dans SQL

SELECT * FROM phones WHERE manu='$manuf' AND price BETWEEN $min AND $max 

Le problème est que tous les champs variables sont connectés à des champs qui seront parfois vides, et donc je besoin d'un moyen de faites-leur correspondre toute valeur que leur champ respectif pourrait prendre s'ils sont vides. J'ai essayé

$min=$_REQUEST['min_price']; 
$max=$_REQUEST['max_price']; 
$manuf=$_REQUEST['manufact']; 
if (empty($min)){ 
    $min=0;} 
if (empty($max)){ 
    $max=900000;} 
if (empty($manuf)){ 
    $manuf='*';} 

qui fonctionne bien pour les champs numériques (bien que je n'aime pas avoir à réglage manuel des limites comme celui-ci), mais je ne peux pas comprendre comment obtenir un match universel pour le champ de texte. Je pensais que * le ferait car il correspond à tous les noms de lignes, mais apparemment pas. Quelqu'un sait-il comment faire ça?

+1

Ce n'est pas le code SQL –

+0

Que voulez-vous dire par «vide»? Une chaîne vide ou une valeur NULL? –

Répondre

1

Si j'étais vous, je couperais le SQL entier en parties, et traitant de l'instruction WHERE.

Somethin comme:

sql = "SELECT * FROM phones WHERE 1=1 " 
if (not empty($manu)) 
    sql = sql + ' AND manu = "$manu"' 
... 

Cordialement.

+0

Si j'étais vous j'éviterais de construire SQL dynamiquement comme ça tous ensemble ... – MatBailie

+0

Oui, mais je suppose que nous savons tous sur l'injection SQL (comme vous l'avez posté après) et comment les éviter. Si quelqu'un est un programmeur paresseux, aucun outil ne changera cela. – ATorras

+0

Juste point, mais je traite avec des programmeurs paresseux tout le temps et une partie de mon travail consiste à minimiser leur impact;) – MatBailie

1

Je suppose que vous voulez en faire une requête de type "filtre" qui permet aux paramètres d'être optionnels? Vous pouvez faire quelque chose comme:

SELECT 
    * 
FROM 
    Phones 
WHERE 
    (manu = $manu OR manu IS NULL) 
    AND (min = $min OR min IS NULL) 
    AND (max = $max OR max IS NULL) 

Ajout OU avec l'option null (vous pouvez le faire une chaîne vide ou autre) vous permet de filtrer sur tout paramètre passé.

Vous pouvez combiner ceci avec ce que vous avez ci-dessus, en vérifiant min/max et en fournissant les valeurs par défaut pour votre clause BETWEEN.

+1

Je pense qu'il veut dire (prix> = $ min OU $ min est nul) et (prix <= $ max OU $ max est nul). Mais s'il vous plaît, Pensez à l'injection SQL. Préparez l'instruction ou au moins utilisez mysql_real_escape_string() pour échapper à l'entrée! –

1

J'ai tendance à le faire en changeant la logique dans le SQL et en passant des paramètres NULL, ou des paramètres avec des valeurs spécifiques.

WHERE manu='$manuf' AND price BETWEEN $min AND $max 

=>

WHERE 
    (manu='$manuf' OR '$manuf' = '*') -- Check for "special value" 
    AND (price >= $min OR $min IS NULL) -- Check for NULL 
    AND (price <= $max OR $max IS NULL) -- Check for NULL 
+1

Note: Je dis que je passe des paramètres, vous construisez une chaîne à exécuter dynamiquement. Comme d'autres l'ont dit à plusieurs reprises, c'est une mauvaise pratique en général, en raison des attaques par injection SQL. Mieux vaut utiliser une méthodologie qui permet le paramétrage. – MatBailie

+0

Il y a toujours des compromis - votre suggestion va souffrir des performances en raison de l'utilisation de l'OR, ce qui détruit la sargabilité. Les injections SQL peuvent être gérées. –

+0

+1 Java a l'objet PreparedStatement qui vous aidera à empêcher l'injection SQL. Cette feuille peut vous aider à archiver cet objectif: http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet – ATorras

0

Peut-être quelque chose comme ...

SELECT * FROM phones 
WHERE manu = coalesce(?, manu) 
AND price >= coalesce(?, price) 
AND price <= coalesce(?, price) 

passent ensuite dans les paramètres au lieu de mettre dans les variables directement (pas sûr de savoir comment faire en PHP off le dessus de ma tête).

Questions connexes