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 ?

82voto

Barmar Points 135986

Si j'ai une application où je construis les IN et qu'elle peut se retrouver vide, ce que je fais parfois, c'est initialiser la liste avec une valeur impossible à atteindre et l'enrichir. Par exemple, si c'est une liste de noms d'utilisateurs, je commence par une chaîne vide, puisque ce n'est pas un nom d'utilisateur possible. S'il s'agit d'un ID à incrémentation automatique, j'utilise -1 car les valeurs réelles sont toujours positives.

Si cela n'est pas faisable parce qu'il n'y a pas de valeurs impossibles, vous devez utiliser une conditionnelle pour décider si vous devez inclure AND column IN ($values) dans l'expression WHERE clause.

24voto

Pavel Shkleinik Points 329

Cela me donne également 0 résultat :

SELECT id FROM User
WHERE id IN (NULL);

Essayé sur MYSQL 5.6

12voto

Asad Points 22968

L'approximation la plus proche de cette requête avec une syntaxe valide est :

SELECT user FROM tbl1 WHERE id IN (SELECT id FROM tbl1 WHERE FALSE);

qui renvoie inconditionnellement un ensemble de résultats vide. La sous-requête entre crochets renvoie toujours un ensemble vide, et aucune valeur ne peut être trouvée dans un ensemble vide, puisqu'un ensemble vide ne contient aucune valeur.

8voto

Jus12 Points 4580

Utilisez une déclaration toujours fausse

Avant de créer le SQL, vérifiez la taille du tableau. Si la taille est égale à 0, générez l'instruction where en tant que 1 = 2 comme dans :

SELECT * FROM USERS WHERE name in () 

devient

SELECT * FROM USERS WHERE 1 = 2 

Pour "not in" sur un tableau vide, générer une déclaration toujours vraie comme dans :

SELECT * FROM USERS WHERE name not in () 

devient

SELECT * FROM USERS WHERE 1 = 1

Cela devrait fonctionner pour des requêtes plus complexes comme :

SELECT * FROM USERS WHERE (name in () OR name = 'Alice') 

devient

SELECT * FROM USERS WHERE (1 = 2 OR name = 'Alice')

5voto

Vous ne pouvez pas laisser IN opérateur vide, vous devez y mettre quelque chose, NULL par exemple. Mais, même dans ce cas, cela ne fonctionnera pas comme prévu, car en comparant avec NULL retourne toujours NULL (vide). Une solution possible est d'ajouter une sous-sélection.

Exemple :

SELECT user_id FROM users;

+-----------+
| user_id   |
+-----------+
|      1000 |
|      1001 |
|      1002 |
|      1003 |
|      1004 |
|      1005 |
|      1006 |
|      1007 |
|      1008 |
|      1009 |
|      1010 |
+-----------+

SELECT user_id FROM users WHERE user_id NOT IN ();
ERROR: 1064: You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near ')' at line 1

SELECT user_id FROM users WHERE user_id NOT IN (NULL);
Empty set (0.0003 sec)    

SELECT user_id FROM users WHERE user_id IN (1001, 1002, 1003) 
AND user_id NOT IN (SELECT user_id FROM users WHERE user_id IN (NULL));
+---------+
| user_id |
+---------+
|    1001 |
|    1002 |
|    1003 |
+---------+
3 rows in set (0.0004 sec)

Vous pouvez un peu modifier (raccourcir) les requêtes, mais je pense qu'elles seront aussi un peu plus lentes.

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