繁体   English   中英

mysql 奇怪的行为就像 false=string 是真的

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM