В UPDATE столбец одновременно участвует в условии отбора и новом значении: какие строки будут изменены?
Строки для изменения определяются по условию WHERE до применения новых значений, поэтому изменение столбца не заставляет SQL повторно проверять условие для той же строки. Каждая квалифицировавшая строка изменяется один раз, если иное не следует из особенностей конкретного запроса, например соединения или триггеров.
SQL создавался как декларативный язык: запрос описывает требуемый результат или изменение данных, а не пошаговый алгоритм обхода строк. Поэтому UPDATE логически разделяет выбор целевых строк и применение новых значений.
Такой подход избавляет разработчика от необходимости вручную управлять порядком обработки строк. Он также позволяет оптимизатору выбирать план выполнения, не меняя логического смысла операции.
Ошибочно представлять UPDATE как цикл, который после изменения каждой строки заново проверяет WHERE. Из-за этого можно ожидать повторное изменение строки или считать, что строка, переставшая соответствовать условию, не будет изменена.
На практике неверное понимание приводит к ошибкам в начислениях, лимитах и переводе записей между состояниями. Особенно опасны массовые обновления, где условие использует тот же столбец, который изменяется.
Сначала SQL определяет набор строк целевой таблицы, удовлетворяющих WHERE. Для каждой строки из этого набора вычисляются выражения SET, после чего результат записывается; новое значение не используется для повторного отбора этой же строки в рамках того же оператора.
Например:
В результате будет изменена только строка с зарплатой 90000. Она станет равна 105000, но не будет затем повторно обработана из-за того, что новая зарплата уже не меньше 100000.
Это логическое правило не означает, что СУБД обязана физически сначала полностью сформировать набор строк, а потом записать изменения. Оптимизатор может выполнять операции иначе, если сохраняется наблюдаемая семантика оператора.
Условие отбора нужно формулировать по исходному состоянию данных. Если требуется многоэтапное изменение, применяют несколько операторов, временную таблицу или общий табличный выраженный результат — в зависимости от СУБД и задачи.
Следует отдельно учитывать триггеры, ограничения и каскадные действия: они могут вызвать дополнительные изменения или ошибки после отбора строк. В конструкциях UPDATE с соединениями поведение при нескольких совпадениях одной целевой строки может зависеть от СУБД, поэтому такие запросы нужно проверять по документации конкретной платформы.
В системе нужно повысить зарплату всем сотрудникам, чья текущая зарплата ниже 100 000. После повышения некоторые сотрудники пересекут этот порог, но не должны получить повышение повторно в рамках одной операции.
Вариант с одним UPDATE прост и атомарен: условие использует исходную зарплату, а изменение выполняется один раз. Это обычно лучший выбор, если бизнес-правило относится к состоянию на момент начала операции.
Пошаговый цикл в прикладном коде хуже: он требует дополнительного чтения, может работать медленнее, усложняет транзакционность и повышает риск частичного выполнения. Несколько SQL-операторов оправданы, если повышение действительно должно происходить поэтапно и каждый этап зависит от результата предыдущего.
Выбранный однократный UPDATE изменяет только сотрудников, прошедших исходный фильтр, и завершает операцию одним массовым изменением. Для контроля результата дополнительно проверяют количество затронутых строк и журналируют операцию.
Да. Условие проверяется для отбора строки до применения нового значения. После присваивания SQL не исключает уже выбранную строку из текущего UPDATE.
Нет. Логический результат не зависит от физического порядка обхода строк, а полагаться на него нельзя. Если выражение обновления зависит от порядка, это обычно признак неверной постановки задачи или необходимости явно моделировать последовательный процесс.
Здесь нельзя переносить общее правило безоговорочно: конкретные СУБД могут по-разному определять результат или допускать неоднозначность. Нужно обеспечить однозначное соответствие источника и цели, например предварительно агрегировать или дедуплицировать источник, а затем свериться с документацией используемой СУБД.