sql中的两种语法有什么区别?

7hiiyaii  于 2021-06-15  发布在  Mysql
关注(0)|答案(2)|浏览(380)

有一张table

mysql> select * from people;

idsexname1남자김준영2남자박민수三여자김영지4남자이준수5남자구준표6여자이윤지7여자이혜리8여자권아영9여자김예지10남자이준필
10行(0.00秒)

mysql> select * from people where 0 and (select 1 union select 2);
Empty set (0.00 sec)

mysql> select * from people where id=50 and (select 1 union select 2);
ERROR 1242 (21000): Subquery returns more than 1 row

我正在解决sql注入问题。在第一种情况下,(select~)命令由于“0”而未执行,并且“0”已为false。
我知道“逻辑运算符短路”
id=50没有列,为什么在下面的情况下会发生错误?

mftmpeh8

mftmpeh81#

另一个答案是误导,因为你所看到的与评价的顺序无关。它与查询的整体处理有关。
sql查询分不同的步骤处理。第一步是编译查询。第二个是优化执行计划,第三个是执行查询。
在优化阶段,mysql检查 where 条款。这被称为常量条件删除,并且有很好的文档记录。
在第一个查询中,mysql看到了常量 0 在条件中,将其识别为false,并且(因为所有。其他条件是 and 取代了 where 带的子句 where 0 . 第二个或附加条件不相关,因此它们被删除。答案在编译过程中是已知的。
在第二种情况下,mysql必须实际查看数据。没有机会进行这样的优化。
确实,表达式在执行阶段的求值顺序也由优化器决定。然而,这与你在这里提出的问题无关。
我非常同意这样的评论和观点,即这不是解决任何类型的sql注入问题的正确方法。事实上,我甚至不知道它有什么帮助。使用参数。

xu3bshqb

xu3bshqb2#

与许多编程语言的工作方式相反,sql引擎可以自由选择一个函数的操作数的顺序 AND 对操作员进行评估。此决策是引擎为查询设计的执行计划的一部分。
在第一种情况下,查询返回而不计算子查询是有意义的,因为0是常量,引擎不需要访问数据就知道不会有结果。
但是,在第二种情况下,引擎确实需要查询表中的第一个条件,因为它事先不知道没有条件 id 值为50。因为它必须真正为此做一个查询,所以它还将考虑子查询。由于该子查询不访问任何表,因此最好先对其求值。当引擎发现它返回2条记录时,这在上下文中是无效的。
至于你的话:
我正在解决sql注入问题。
这样解决sql注入问题是一种非常糟糕的做法。您应该编译sql语句,并将变量绑定到已编译的语句。这就是如何以可靠的方式防止sql注入。

相关问题