[英]mysql weird behavior acting like false=string is true
我正在测试一些查询,但得到了一个奇怪的结果。
我测试了以下查询
SELECT * FROM Persons where username = 'admin' and password = username = 'a'
这将返回管理员的信用(用户名和密码)
因此,如果我是正确的,则password = username = 'a'
将返回 true..
但是怎么样?
所以我测试了更多的查询并得到以下结果
Select 1 from Persons where 1=1='a';//returns nothing
select 1 from Persons where 1=2='a';//returns 1
所以 true='a' 是假的,而 false='a' 是真的?
谢谢,
大概是这样的:
password = username
返回false
对于 MySql 被评估为0
。
然后这个:
0 = 'a'
在 MySql 隐式尝试将'a'
转换为数字以评估表达式后,由于'a'
无法转换为数字,因此转换结果为0
。
您可以在此处找到有关隐式转换的所有信息:12.3表达式计算中的类型转换。
所以:
0 = 0
返回true
。
Mysql 将变量强制转换为左变量类型。 所以表达式password = username = 'a'
可以这样表达:
password = username
// 0 (false)
0 = 'a'
// 1 (true),因为 CAST('a' AS INTEGER) = 0
与1=1='a'
: 1=1
// 1 (true) 1='a'
// 0 (false),因为 CAST('a' AS INTEGER) = 0
对于1=2='a'
:
1=2
// 0(假)
0='a'
// 1 (true),因为 CAST('a' AS INTEGER) = 0
您可以尝试下一个查询来检查这些内容:
SELECT "string1" = "string2", 0 = "a", CAST('a' AS INTEGER);
首先,当你做x=y=z
,真正发生的是(x=y)=z
意味着你正在比较password = username
(false,对于每个知道如何选择强密码的用户......) '一种'。
现在,关于 mySql 中布尔值的事情是它们被表示为 tinyint - 1 为真,0 为假。 您可以通过运行select true
看到 - 结果为 1。
这也适用于字符串 - '1' 与布尔值相比为真,任何其他字符串为假,你可以运行这两个,看看你会得到 1 作为结果:
select true = 1;
select true = '1';
select false = 0;
select false = '0';
select false = 'any other string';
MySQL 将 false 视为 0,将 true 视为 1。这允许特定于 MySQL 的黑客,例如
SELECT COUNT(*), SUM(active = 1) active, SUM(active <> 1)inactive FROM tbl
做一些温和的枢轴式报告。
看起来 MySQL 对包含多个比较器的 WHERE 子句的处理是从左到右运行的。 所以
SELECT 1 = 1
给出 1,这两个等价表达式也是如此。
SELECT 1 = 1 = 1, (1 = 1) = 1
现在, 0 = 'a'
返回 1(真),因为另一个 MySQL 怪癖通过将字符串的前导数字解释为整数来将字符串强制为整数。 所以7 = '7a'
是 1(真), 0 = '0a'
(和0 = 'a'
)。 但是6 = '7a'
是假的 (0)。
这个故事的主旨? 为了获得清晰的代码,请避免使用多个比较器的 WHERE 子句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.