Запрос UPDATE изменил строки без предложения WHERE, но имел предложение AND - почему? - PullRequest
3 голосов
/ 31 августа 2011

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

Ответы [ 2 ]

4 голосов
/ 31 августа 2011

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

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

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

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

Я бы предположилу вас есть 96 строк в tblFormElementInstances, но только 94 из этих строк имеют совпадающую строку в tblFormElements.JOIN означает, что только соответствующие строки имеют право на UPDATE.

Попробуйте этот запрос, чтобы проверить эту теорию. Могу поспорить, он вернется 94:

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

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

1 голос
/ 31 августа 2011
  1. Не уверен.Я согласен, что одинокий ) должен был привести к синтаксической ошибке.Возможно, MySQL не такой строгий.
  2. Потому что результат 1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL был 0.Как вы сами отметили, что первым AND должно было быть WHERE
  3. Скорее всего, ваш JOIN не соответствует 2 строкам из другой таблицы.
...