UPDATE 查询在没有 WHERE 子句的情况下更改了行,但有 AND 子句 - 为什么?

发布于 2024-12-02 17:08:36 字数 593 浏览 0 评论 0原文

我运行了以下查询,它应该有一个 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 行,具有不同的 intDivisionId(即不仅仅是 1 或 NULL),这表明 MySQL 完成了一些过滤(匹配的行 = 94)。

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

有谁知道:

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

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

I ran the following query, which should have had a where clause but I forgot to add it:

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

MySQL returned the following message:

--Query OK, 42 rows affected (0.06 sec)
--Rows matched: 94 Changed: 42 Warnings: 0

I would have expected it to throw a syntax error, but it didn't. Additionally there are 96 rows in that table, with differing intDivisionIds (i.e. not just 1 or NULL), which suggests that some filtering was done by MySQL (rows matched = 94).

Also, intStep was actually changed to 0, not 1.

Does anyone know:

1) Why this query worked at all?
2) Why it changed intStep to 0 and not 1?
3) Why it didn't match all 96?

(The changed count of 42 is because some rows already had intStep = 1.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

违心° 2024-12-09 17:08:36

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

您将 intStep 设置为这个表达式(我添加了括号来显示优先级):

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

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

我猜测 tblFormElementInstances 中有 96 行,但其中只有 94 行在 tblFormElements 中有匹配行。 JOIN 意味着只有匹配的行才有资格进行更新。

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

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

@Jason McCreary 很好地观察到您在示例末尾有一个不平衡的括号。这应该会导致语法错误。既然你说你没有收到语法错误,我假设你的示例中错误地包含了括号。

It works without a syntax error because 1 AND <expr> is a valid expression.

You set intStep to this expression (I have added parentheses to show precedence):

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

That's a boolean expression that is either 0 or 1, and so it changes some rows to 0 and some rows to 1. It changes to 0 if intDivisionId is not 1, and if intDivisionId is not null.

I would guess you have 96 rows in tblFormElementInstances, but only 94 of these rows have a matching row in tblFormElements. The JOIN means only matching rows are eligible for the UPDATE.

Try this query to test this theory, I bet it'll return 94:

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

@Jason McCreary makes a good observation that you have an imbalanced parenthesis at the end of your example. That should result in a syntax error. Since you say you didn't get a syntax error, I assume that parenthesis is included in your example by mistake.

初吻给了烟 2024-12-09 17:08:36
  1. 没有把握。我同意尾随的、单独的 ) 应该会导致语法错误。也许MySQL没有那么严格。
  2. 因为1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL的结果是0。正如您自己所指出的,第一个 AND 应该是 WHERE
  3. 很可能您的 JOIN中的 2 行不匹配>其他表。
  1. Not sure. I agree the trailing, lone ) should have resulted in a syntax error. Maybe MySQL is not that strict.
  2. Because the result of 1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL was 0. As you noted yourself, that first AND should have been a WHERE
  3. More than likely your JOIN didn't match 2 rows out of the other table.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文