2010-05-20 4 views
10

regard sur ce tableau s'il vous plaîtselect ... où id = n'importe quelle valeur. c'est possible?

table 
|id| |name| |order| 

je dois obtenir les lignes, où name = something et order = somevalue

donc j'écrire

select `id` from `table` where `name` = 'something' and `order` = 'somevalue' 

mais dépendent de la logique php, je dois parfois obtenir tous lignes, où name = something, indépendamment de order valeur. Je ne veux pas changer la structure de la requête, car en pratique il y a beaucoup de champs, et le nombre de requêtes possibles deviendra très important. donc je veux sauver la structure de requête, et quand je dois choisir simplement par son nom, je veux écrire quelque chose comme ceci:

select `id` from `table` where `name` = 'something' and `order` = any value 

est-il possible?

grâce

+1

je changerais la façon dont vous construisez vos questions ... – nickf

Répondre

10

Eh bien, c'est un peu un hack, mais si vous avez vraiment besoin de le faire, cela fonctionnera comme ceci:

select `id` from `table` where `name` = 'something' and `order` = `order` 

Alors vous venez de dire « où l'ordre est le même que lui-même ", donc c'est toujours vrai.

+2

je considère cette modification de la structure, car la syntaxe pour faire référence à un champ n'est pas la même que celle de se référer à une chaîne. –

+0

Ce n'est pas la bonne façon de procéder. Le code php doit être ajusté. – vonPetrushev

5

Non, ce n'est pas possible. Vous devez changer la structure (optionnellement un LIKE de sorte que vous puissiez utiliser '%', mais c'est très moche). Toutefois, vous n'avez pas besoin d'écrire une requête différente pour gérer toutes les combinaisons possibles. Vous pouvez simplement créer la requête dynamique:

//create base query 
$query = "select `id` from `table` where `name` = 'something' "; 

//add order if we need it 
if ($use_order) 
    $query .= "and `order` = 'somevalue' "; 

//repeat for any other optional part 

Notez que vous devez bien sûr prendre encore des mesures appropriées pour éviter l'injection SQL et d'autres problèmes de sécurité - je ne l'ai pas compris ce ici afin de garder les choses simples.

+0

Qu'est-ce que l'injection SQL? peut-être parlez-vous de mysql_real_escape_string() et de telles fonctions? Je ne comprends pas la signification de "injection SQL" – Simon

+0

@Syom: L'injection SQL est l'acte de fournir des données qui affecte la structure de la requête, l'amenant à faire autre chose que ce qu'il était censé faire. mysql (i) _real_escape_string est en effet ce que la plupart des gens utilisent pour éviter cela (bien que les requêtes paramétrées soient à proprement parler une meilleure approche, mais c'est un sujet différent). Si vous voulez en savoir plus, il y a beaucoup de bonnes ressources, à la fois sur SO et disponibles via Google. Tout ce que j'essaie de dire, c'est que vous devez toujours vous souvenir de faire ce genre de chose lors de la construction dynamique. –

2

Si vous utilisez des paramètres liés, ce serait impossible.

Si vous remplacez simplement les valeurs, vous pouvez effectuer les opérations suivantes:

select `id` from `table` where `name` = 'something' and `order` = `order` 
0

Je ne pense pas que vous avez le choix ... Une fois que vous faites une sélection vous ne pouvez pas « unfilter » et obtenez plus de lignes.

Vous devez simplement utiliser deux requêtes: soit deux requêtes indépendantes, soit une qui sélectionne le nom dans une table temporaire, puis (facultativement) une autre qui sélectionne l'attribut order.

0

Comme le dit Tchad ci-dessus, il suffit de mettre la colonne égale à elle-même. Mais attention, sur certaines plates-formes/installer des configurations, NULL = NULL:

select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'') 
+4

NULL! = NULL est en fait le comportement attendu, tel que défini dans la norme SQL. –

0

C'est un thème commun avec les requêtes de base de données - vous avez besoin d'une requête variable selon la quantité de filtrage que vous souhaitez appliquer aux données qu'il! requêtes. Vous pouvez faire en sorte que votre requête soit répétée sous forme de chaîne dans tout votre code, mais c'est une mauvaise pratique car cela augmente inutilement la complexité du code. Il y a des risques d'erreurs si vous avez besoin de modifier la requête pour une raison quelconque et que vous devez la modifier à plusieurs endroits.

La meilleure solution est de créer une fonction qui construit la requête pour que vous exécutez:

function buildMyQuery($name, $order = null) { 
    $sql = "SELECT `id` FROM `table` WHERE `name`='$name'"; 

    if ($order != null) { 
     $sql .= " AND `order`='$order'"; 
    } 

    return $sql; 
} 

Vous pouvez ensuite exécuter ce pour juste en utilisant le champ « Nom »:

$query = buildMyQuery("somename"); 

Ou cette pour utiliser les deux champs:

$query = buildMyQuery("somename", "someorder"); 

Comme mentionné ci-dessus, ce code est délibérément simp lifié et ne contient aucune éventualité pour des données potentiellement dangereuses transmises via $ name ou $ order. Vous devrez utiliser mysql_real_escape_string ou quelque chose de similaire pour nettoyer les données en premier, au début de la fonction avant que l'une ou l'autre donnée ne soit utilisée. La génération de requêtes dynamiques est une réalité de la vie, comme le dit Byron, donc je m'y habituerais maintenant plutôt que d'utiliser des solutions de rechange hack-ish.

0

Après réflexion, j'ai une meilleure réponse. Mon collègue m'a montré comment cela peut être fait.

Mon exemple ...

Select rentals.* From rentals Where ((? = '') OR (user_id = ?)) 

Les variables doivent être identiques.

Si elles sont à la fois 5 par exemple, le premier booléen faux, mais le second sera vrai, pour les lignes où l'identification des utilisateurs est 5.

Si vous avez besoin « tout », en guise d' chaîne vide entraînera que toutes les lignes sont considérées comme respectant la condition de clause where.

0

Vous ne pouvez pas utiliser ici une requête not null?

select `id` from `table` where `name` = 'something' and `order` is not null; 
Questions connexes