刚刚艰难地学习了一段 MySQL sytax - 为什么它有效,它意味着什么?

Just learned the hard way a piece of MySQL sytax - why does this work and what does it mean to do?

我正在使用 MySQL 5.6。我公司的内部应用程序使用 SET SQL_SAFE_UPDATES = 0;(我知道)。我之前曾提出过这个问题,但被告知随它去吧。

今天不小心写了运行这个 DELETE FROM table WHERE id - 11235,用 - 而不是 =,你瞧,所有的行都被删除了。我知道在关闭安全更新的情况下允许删除所有行,但为什么这没有引发语法错误? id - 11235 在 SQL 中甚至意味着什么?

您有一个带有条件 (WHERE) 的 DELETE 语句。如果该行的条件为真,则删除操作正在完成。

您的条件是id - 11235。此条件不产生 false/0 的每一行都被视为 true。因此,该命令将删除除 id 11235 (11235-11235 = 0) 之外的所有行。

这在 MySQL 中有效,因为 MySQL 对于 SQL 布尔表达式是非标准的。

布尔表达式的计算结果必须为 truefalse。但在MySQL中,false只是整数0,true是整数1,除0以外的任何其他整数也被视为真。

所以很奇怪,不符合 ANSI SQL,但是任何算术表达式也可以用作布尔表达式,反之亦然。

这让我们可以像这样做巧妙的技巧:

SELECT SUM( name = 'Harry' ) FROM mytable

布尔表达式产生整数值,0 或 1,具体取决于字符串比较。有效地总结这些 returns 表达式为真的行数,就好像我们有 运行:

SELECT COUNT(*) FROM mytable WHERE name = 'Harry'

但是 SUM 技巧允许我们通过 table:

的单次传递来 "count" 多个条件
SELECT SUM(name = 'Harry'), SUM(name = 'Ron'), SUM(name = 'Hermione') FROM mytable

您不能使用 COUNT(*) 和 WHERE 子句来做到这一点。

同样,这仅适用于 MySQL,因为 MySQL 使布尔值和整数相同。它在 SQL.

的其他实现中不起作用

在您的查询中,id - 11235 在 id = 11235 的行上为 0,并且在其他每一行上都为非零。它非零的行被视为 true,因此应用删除。

这至少对你来说是不幸的,因为输入错误会导致你的所有数据被删除。