Запрос UPDATE изменил строки без предложения WHERE, но с предложением AND — почему?

Я выполнил следующий запрос, в котором должно было быть предложение 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.)


person beingmrkenny    schedule 31.08.2011    source источник
comment
Должна быть синтаксическая ошибка, потому что закрывающая скобка не имеет соответствия.   -  person bart    schedule 31.08.2011
comment
Да, извините, после И была скобка, которую я должен был удалить, когда вставлял запрос.   -  person beingmrkenny    schedule 02.09.2011


Ответы (2)


Это работает без синтаксической ошибки, потому что 1 AND <expr> является допустимым выражением.

Вы устанавливаете intStep в это выражение (я добавил круглые скобки, чтобы показать приоритет):

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

Это логическое выражение, которое равно 0 или 1, поэтому оно изменяет некоторые строки на 0, а некоторые строки на 1. Оно изменяется на 0, если intDivisionId не равен 1 и если intDivisionId не равен null.

Я предполагаю, что у вас есть 96 строк в tblFormElementInstances, но только 94 из этих строк имеют соответствующую строку в tblFormElements. JOIN означает, что только совпадающие строки имеют право на ОБНОВЛЕНИЕ.

Попробуйте этот запрос, чтобы проверить эту теорию, держу пари, он вернет 94:

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

@Jason McCreary делает хорошее замечание, что в конце вашего примера есть несбалансированная скобка. Это должно привести к синтаксической ошибке. Поскольку вы говорите, что не получили синтаксической ошибки, я предполагаю, что круглые скобки включены в ваш пример по ошибке.

person Bill Karwin    schedule 31.08.2011
comment
Великолепно, спасибо, что ответили на него отлично! Вы были правы, этот запрос на выборку возвращает 94. - person beingmrkenny; 02.09.2011

  1. Точно сказать не могу. Я согласен, что замыкание, одинокое ) должно было привести к синтаксической ошибке. Возможно, MySQL не такой строгий.
  2. Потому что результат 1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL был 0. Как вы сами заметили, этот первый AND должен был быть WHERE
  3. Скорее всего, ваш JOIN не соответствует 2 строкам из таблицы other.
person Jason McCreary    schedule 31.08.2011
comment
1 - я пропустил открывающую скобку сразу после И, сомневаюсь, что MySQL такой слабый :) - person beingmrkenny; 02.09.2011