Pourquoi, dans MySQL, est-ce que cet IF retourne faux?
-
07-07-2019 - |
Question
Dans MySql, si le premier argument d'une fonction IF () est une chaîne, pourquoi renvoie-t-il false?
SELECT IF('string', 'string', 'not string'); -- 'not string'
Bien sûr, je pourrais régler ce problème si je le faisais
IF(!ISNULL('string'), 'string', 'not string')) -- 'string'
ou
IFNULL('string', 'not string'); -- 'string'
Il semble quelque peu contre-intuitif d'évaluer une chaîne de la même manière que si
SELECT IF(1, 'one', 'not one'); -- 'one'
et
SELECT IF('1', 'one', 'not one'); -- 'one'
évaluez la façon dont ils le font ...
La solution
De MySQL
IF (expr1, expr2, expr3)
Si expr1 est VRAI (expr1 < > 0 et expr1 < > NULL), alors IF () renvoie expr2; sinon, il retourne expr3. IF () renvoie un chiffre ou une chaîne valeur, en fonction du contexte dans lequel il est utilisé.
Donc 1 est vrai parce que 1! = 0 et 1! = NULL. C'est comme ce que vous verriez dans C.
Mais pour une chaîne, dire qu'un "test" est évalué comme vrai n'a pas de fondement réel dans la définition et n'a pas de sens logique. Cela doit être comparé à quelque chose qui donne un résultat booléen.
Autres conseils
Le premier argument donné à IF()
est un prédicat . Une chaîne n'est pas considérée comme un prédicat par MySQL, elle est donc définie par défaut sur false. Pour ce qui est de votre dernier cas, beaucoup de langages (C, Perl, etc.) considèrent que les entiers non nuls sont vrais, alors MySQL ne fait que supporter ce paradigme.
Parce que 'chaîne' n'est ni vrai ni faux et que la première expression doit être évaluée à un booléen.
Pourquoi IF (1, ...) est-il vrai? Bonne question. Peut-être un retour en C (c'est-à-dire si c'est 1, alors c'est vrai)?
EDIT: En fait, selon la définition de la commande sous http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if , expr1 est VRAI si expr1 < > ; 0 et expr1 & Lt; & Gt; NULL, ce qui est le cas lorsque expr1 == 1.
Notez qu'il existe des similitudes en PHP:
"string" != 0 // false
"one" != 0 // false
"1" != 0 // true
La confusion semble se produire car MySQL compare 0 (et null) pour obtenir la valeur booléenne de quelque chose. Dans d'autres langues, comme PHP et Javascript, une chaîne, lorsqu'elle est convertie en boolean, renvoie true lorsqu'elle est non vide (ou non & "; 0 &";).
// php
0 == true // false
"string" == 0 // true*
"string" == true // true
// mysql
if(0, "true", "false") // false
if("string", "true", "false") // false*
Les deux *
lignes étoilées <=> présentent les comparaisons équivalentes, si vous voyez ce que je veux dire.