Quelqu'un sait-il pourquoi cette requête renvoie des résultats alors qu'elle ne le devrait pas? Le code de la requête a un x supplémentaire, mais le code de la base de données n'en a pas.

SELECT * FROM `otp` WHERE `code`= '1623x' AND `userid`='4' AND `status`='1'

enter image description here

Merci d'avance...

Morgs

2
Morgs 15 sept. 2020 à 01:29

3 réponses

Meilleure réponse
WHERE `code`= '1623x' 

Je soupçonne fortement que code est une colonne numérique.

Si c'est le cas: pour évaluer la condition, MySQL doit comparer un nombre à une chaîne. Il contraint la chaîne à un nombre, puis effectue une comparaison numérique. Il s'avère que la chaîne '1623x' se traduit par le nombre 1623, donc la condition est remplie.

Si, par exemple, la chaîne avait été 'x1623', elle aurait été convertie en 0 (car elle ne commence pas par un chiffre), et vous n'auriez pas reçu de résultat.

En un mot: ne comparez pas les valeurs de différents types de données. Chaque base de données a sa propre compréhension de ce qui devrait se passer dans ce cas, ce qui peut vous sembler intuitif ou non.

2
GMB 14 sept. 2020 à 22:33

Ce que vous voyez est dû aux règles particulières de casting de MySQL. Lorsque vous essayez de comparer la chaîne littérale '1623x' à l'entier 1623, MySQL doit d'abord faire quelque chose pour amener le LHS et le RHS au même type. La seule façon de le faire est de convertir '1623x' en un entier. Les règles de conversion sont telles que si la chaîne commence par un entier, MySQL conservera autant de chiffres disponibles. Dans ce cas, '1623x' devient l'entier 1623, et ainsi LHS et RHS deviennent vrais.

Pour être clair, voici la requête qui évalue pour produire l'enregistrement inattendu:

SELECT *
FROM otp
WHERE 1623 = 1623 AND userid = 4 AND status = 1;
2
Tim Biegeleisen 14 sept. 2020 à 22:34

MySQL utilise le type de l'opérande droit pour convertir l'opérande gauche. Si vous avez une colonne de type entier code et que vous dites code = '123abc', cela devient équivalent à code = 123 (avec un avertissement). Si vous voulez éviter que cela (ainsi que des choses comme code = '00123' ou code = '123.0') ne trouve 123, ajoutez une condition where supplémentaire pour effectuer également une comparaison de chaînes:

and code='123abc' and concat(code)='123abc'

(ou utilisez cast au lieu de concat). Je suggère une comparaison supplémentaire plutôt que de simplement remplacer celle existante afin que le code puisse toujours être utilisé pour les recherches d'index.

1
ysth 14 sept. 2020 à 22:56