开发者

UPDATE query changed rows without a WHERE clause but had an AND clause - why?

开发者 https://www.devze.com 2023-04-01 11:26 出处:网络
I ran the following query, which should have had a where clause but I forgot to add it: UPDATE tblFormElementInstances as fei

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.)


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.


  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.
0

精彩评论

暂无评论...
验证码 换一张
取 消