【问题标题】:UPDATE query changed rows without a WHERE clause but had an AND clause - why?UPDATE 查询更改了没有 WHERE 子句但有 AND 子句的行 - 为什么?
【发布时间】:2011-08-31 16:12:32
【问题描述】:

我运行了以下查询,它应该有一个 where 子句,但我忘了添加它:

UPDATE
tblFormElementInstances as fei
JOIN
tblFormElements as fe using(intFormElementId)
SET
fei.intStep = 1
AND
fei.intDivisionId = 1 OR fei.intDivisionId IS NULL);

MySQL 返回以下消息:

--查询正常,影响 42 行(0.06 秒)
--匹配行:94 更改:42 警告:0

我原以为它会引发语法错误,但事实并非如此。此外,该表中有 96 行,具有不同的 intDivisionIds(即不仅仅是 1 或 NULL),这表明 MySQL 完成了一些过滤(匹配的行数 = 94)。

另外,intStep 实际上改为 0,而不是 1。

有谁知道:

1) 为什么这个查询有效?
2) 为什么将 intStep 更改为 0 而不是 1?
3) 为什么不匹配所有 96?

(更改为 42 的计数是因为某些行已经有 intStep = 1。)

【问题讨论】:

  • 这里必须有语法错误,因为右括号不匹配。
  • 是的,抱歉,AND 后面有一个括号,我在粘贴查询时必须删除它。

标签: mysql where


【解决方案1】:

它没有语法错误,因为1 AND <expr> 是一个有效的表达式。

您将 intStep 设置为该表达式(我已添加括号以显示优先级):

SET intStep = ((1 AND (fei.intDivisionId = 1)) OR (fei.intDivisionId IS NULL))

这是一个布尔表达式,为 0 或 1,因此它将某些行更改为 0,将某些行更改为 1。如果 intDivisionId 不为 1,并且如果 intDivisionId 不为 null,则更改为 0。

我猜你在 tblFormElementInstances 中有 96 行,但这些行中只有 94 行在 tblFormElements 中有匹配的行。 JOIN 意味着只有匹配的行才有资格进行 UPDATE。

试试这个查询来测试这个理论,我敢打赌它会返回 94:

SELECT COUNT(*) FROM tblFormElementInstances as fei
JOIN tblFormElements as fe using(intFormElementId)

@Jason McCreary 很好地观察到您的示例末尾有一个不平衡的括号。这应该会导致语法错误。由于您说您没有收到语法错误,因此我认为括号是错误地包含在您的示例中。

【讨论】:

  • 太棒了,谢谢你完美的回答!你是对的,选择查询返回 94。
【解决方案2】:
  1. 不确定。我同意尾随的单独) 应该导致语法错误。也许 MySQL 没有那么严格。
  2. 因为1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL 的结果是0。正如您自己指出的那样,第一个 AND 应该是 WHERE
  3. 您的 JOIN 很可能与 other 表中的 2 行不匹配。

【讨论】:

  • 1 - 我在 AND 之后错过了一个开头的括号,怀疑 MySQL 是否松懈 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多