114 votes

Liste vide de paramètres de clause IN dans MySQL

Que se passe-t-il lorsque vous faites une requête SQL où le IN est vide ?

Par exemple :

SELECT user WHERE id IN ();

Est-ce que MySQL traitera ce cas comme prévu (c'est-à-dire toujours faux), et si ce n'est pas le cas, comment mon application peut-elle gérer ce cas lors de la construction de la base de données ? IN de façon dynamique ?

4voto

Manic Depression Points 480

Si vous utilisez AUTO_INCREMENT pour les id (1,2,3, ..) et si le tableau est vide, vous pouvez ajouter un élément [0]. Ce sera donc

if (empty($arr)) {
   $arr[] = 0;
}

SELECT user WHERE id IN (0);

Et il n'y aura pas d'erreur d'analyse mysql. Ce cas est très utile dans les sous-requêtes - lorsque votre requête principale ne dépend pas des résultats de la sous-requête.


Meilleur moyen - ne pas appeler la requête si le tableau est vide.

$data = null;
if (!empty($arr)) {
    $data = ... call query
}

2voto

Vadzim Points 4460

Voici une autre variante de la déclaration toujours fausse pour les listes vides qui préserve à la fois la logique et la notion de colonne réelle dans la requête.

Incorrect id in () peut être réécrit en :

where id <> id;

Condition négative incorrecte similaire id not in () peut être transformé par un code de construction de requête personnalisé en :

where id = id;

Cette approche est plus sûre que id not in (NULL) car il n'est pas évalué à NULL.

Mais attention à ce que cela élimine du résultat les lignes où id is null . Cela peut être considéré comme une caractéristique dans certains cas.

Particulièrement utile avec la logique de construction de requêtes empilées complexes où le constructeur imbriqué ne sait pas comment la sous-requête résultante pourrait être utilisée au-dessus.

2voto

Zehelvion Points 1428

Une façon de gérer cela :

SELECT user WHERE id in (SELECT 1 WHERE 1!=1)

Il pourrait être nécessaire de remplacer 1 par une valeur du type de données approprié, comme mentionné dans un commentaire de @JamesHoux.
On suppose ici que l'id d'un utilisateur est un int.

1voto

Arth Points 2209

Je suppose que vous avez toujours besoin d'exécuter la requête quand votre IN est vide ; par exemple avec LEFT JOIN ... ON ... AND IN () .

Comme vous construisez déjà dynamiquement le IN dans la couche application, je traiterais le cas vide là-bas.

Voici un exemple de base en PHP

$condition = 'FALSE' // Could feasibly want TRUE under different circumstances
if($values){
   $inParams = **dynamically generated IN parameters from $values**;
   $condition = 'IN (' . $inParams . ')';
}

$sql = 'SELECT * FROM `user` WHERE '.$condition;

Si vous n'avez pas besoin d'exécuter la requête avec un fichier vide IN alors ne le faites pas ; vous vous épargnerez un voyage à la base de données !

N.B. Au cas où vous ne le feriez pas déjà, je construirais/utiliserais une fonction qui va dans le sens inverse et qui lie dans votre IN correctement, plutôt que de les concaténer brutalement dans le SQL. Cela vous donnera une certaine protection contre l'injection SQL si elle est utilisée sur des données brutes.

-1voto

chikebox Points 101

Si vous utilisez cette requête dans une application et que vous passez dynamiquement une liste d'objets à la requête, je ne devrais pas appeler la base de données pour faire une sélection avec une valeur impossible, je devrais retourner une liste vide sans appeler la requête de la base de données, directement.

Parce que cela n'a aucun sens de faire une requête dont on sait qu'elle est vide avant de l'appeler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X