SQLUPDATEDMLtutorial

Что такое UPDATE в SQL?

UPDATE — это команда «поменять данные в существующих строках». Простыми словами: что меняем, как обязательно сужать WHERE, как поменять сразу несколько колонок. Таблицы before/after, типичные ловушки новичков, мини-резюме и три задачки на закрепление.

10 мин чтенияСправочникSQL · UPDATE · DML · tutorial

UPDATE — это команда, которая изменяет данные в уже существующих строках.

Не добавляет новые строки — для этого есть INSERT.
Не удаляет строки — для этого есть DELETE.
А именно исправляет то, что уже лежит в таблице.

Представь таблицу как блокнот с контактами.
INSERT — это добавить нового человека.
DELETE — вычеркнуть человека из блокнота.
А UPDATE — аккуратно заменить старый номер телефона на новый, потому что человек переехал или сменил SIM-карту.

В SQL это одна из самых важных команд. И одновременно одна из тех, с которыми нужно быть особенно внимательным: UPDATE действительно меняет данные.

Зачем нужен UPDATE

Данные в реальной жизни постоянно меняются.

Пользователь сменил email.
Заказ оплатили.
Товар подорожал.
Сотруднику повысили зарплату.
Статью перевели из черновика в опубликованное состояние.
Клиент накопил бонусные баллы.

Во всех этих случаях строка уже есть в таблице. Нужно просто поменять одно или несколько полей.

Например:

Ситуация Что меняем
Пользователь подтвердил email is_verified
Заказ оплатили status
Товар стал дороже price
Клиент перешёл на платный тариф tier
Пост опубликовали published_at

Если бы UPDATE не было, пришлось бы удалять строку и вставлять новую. Это плохая идея: можно потерять связи, историю, внешний ключ, старый id и получить много лишних проблем.

UPDATE нужен, чтобы менять данные точечно и безопасно.

Базовый синтаксис

Общий вид такой:

UPDATE table_name
SET column_name = new_value
WHERE condition;

По частям:

  • UPDATE table_name — какую таблицу обновляем;
  • SET column_name = new_value — какую колонку и на какое значение меняем;
  • WHERE condition — какие строки нужно обновить.

Например:

UPDATE users
SET tier = 'gold'
WHERE id = 1;

Читается так:

В таблице users найди пользователя с id = 1 и измени у него колонку tier на значение 'gold'.

Вот и вся базовая идея.

Пример с таблицей пользователей

Допустим, есть таблица users.

id name email tier
1 Аня anya@example.com free
2 Боб bob@example.com free
3 Вера vera@example.com gold

Аня купила платный тариф. Нужно поменять её тариф с free на gold.

UPDATE users
SET tier = 'gold'
WHERE id = 1;

После запроса таблица станет такой:

id name email tier
1 Аня anya@example.com gold
2 Боб bob@example.com free
3 Вера vera@example.com gold

Что важно заметить:

  • изменилась только одна строка;
  • изменилась только одна колонка;
  • остальные данные Ани остались прежними;
  • Боб и Вера не изменились, потому что их не пропустило условие WHERE id = 1.

UPDATE не переписывает всю таблицу с нуля. Он меняет только то, что ты попросил.

SET: что именно меняем

Часть SET отвечает за новые значения.

Например:

UPDATE products
SET price = 1200
WHERE id = 10;

Здесь мы говорим: у товара с id = 10 поставить цену 1200.

Можно менять строку:

UPDATE orders
SET status = 'paid'
WHERE id = 500;

Можно менять дату:

UPDATE posts
SET published_at = NOW()
WHERE id = 7;

Можно менять логическое значение:

UPDATE users
SET is_verified = TRUE
WHERE id = 1;

SET — это место, где ты описываешь новую версию данных.

Можно обновить несколько колонок сразу

В одном UPDATE можно изменить не одну колонку, а сразу несколько.

Например, пользователь купил платный тариф, и мы хотим:

  • изменить тариф;
  • записать дату обновления;
  • отметить, что пользователь подтверждён.
UPDATE users
SET
  tier = 'gold',
  upgraded_at = NOW(),
  is_verified = TRUE
WHERE id = 1;

Обрати внимание на запятые между присваиваниями.

Такой запрос выполняет все изменения вместе. Это лучше, чем делать три отдельных UPDATE, потому что данные не окажутся в странном промежуточном состоянии.

Например, не будет ситуации, где тариф уже gold, а дата обновления ещё пустая. База применяет изменение как одну операцию.

WHERE — самая важная часть UPDATE

WHERE отвечает на вопрос:

Какие строки нужно изменить?

Именно здесь чаще всего происходят дорогие ошибки.

Вот безопасный запрос:

UPDATE users
SET tier = 'gold'
WHERE id = 1;

Он обновит только пользователя с id = 1.

А вот опасный запрос:

UPDATE users
SET tier = 'gold';

Здесь нет WHERE.

Значит, база обновит все строки таблицы.

Если в таблице 3 пользователя — все станут gold.
Если в таблице 3 миллиона пользователей — все 3 миллиона станут gold.

База не спросит: «Ты уверен?»
Она просто выполнит команду.

Поэтому главное правило:

почти каждый UPDATE должен быть с WHERE.

Без WHERE обновление всех строк тоже иногда нужно, но это уже осознанная массовая операция. Для новичка безопаснее считать, что WHERE обязателен.

Привычка: сначала SELECT, потом UPDATE

Перед тем как менять данные, полезно сначала посмотреть, какие строки попадут под условие.

Допустим, ты хочешь обновить пользователя с id = 42.

Сначала проверь:

SELECT
  id,
  name,
  tier
FROM users
WHERE id = 42;

Посмотрел результат. Убедился, что это нужный пользователь.

Только потом запускай:

UPDATE users
SET tier = 'gold'
WHERE id = 42;

Это простая привычка, которая спасает от многих неприятностей.

Особенно на рабочей базе.

Схема такая:

  1. Написал SELECT с нужным WHERE.
  2. Проверил строки глазами.
  3. Убедился, что всё правильно.
  4. Выполнил UPDATE с тем же WHERE.

Не ленись делать этот шаг. Он занимает несколько секунд, а может сэкономить часы восстановления данных.

UPDATE внутри транзакции

Если база поддерживает транзакции, опасные обновления лучше делать внутри BEGIN и COMMIT.

BEGIN;

UPDATE users
SET tier = 'gold'
WHERE email = 'anya@example.com';

COMMIT;

Смысл транзакции простой: ты открываешь «режим черновика», выполняешь изменение, проверяешь результат и только потом окончательно сохраняешь.

Если что-то пошло не так, можно сделать откат:

BEGIN;

UPDATE users
SET tier = 'gold'
WHERE email = 'anya@example.com';

ROLLBACK;

ROLLBACK отменит изменения внутри текущей транзакции.

В PostgreSQL после UPDATE обычно видно, сколько строк обновилось. Например:

UPDATE 1

Это значит: обновлена одна строка.

Если ты ожидал одну строку, а увидел:

UPDATE 247

лучше остановиться и разобраться. Возможно, условие оказалось слишком широким.

RETURNING: сразу увидеть, что изменилось

В PostgreSQL у UPDATE есть очень удобная возможность — RETURNING.

Она позволяет сразу вернуть обновлённые строки.

UPDATE users
SET tier = 'gold'
WHERE id = 1
RETURNING id, name, tier;

Так ты не только обновляешь данные, но и сразу видишь результат.

Это особенно удобно, когда:

  • нужно проверить, что обновилась правильная строка;
  • приложение должно получить новое значение;
  • ты хочешь увидеть итог без отдельного SELECT.

Например:

UPDATE orders
SET status = 'paid'
WHERE id = 500
RETURNING id, status, updated_at;

Для обучения это очень приятная команда: она помогает видеть результат прямо после изменения.

Условия в WHERE могут быть сложными

В WHERE можно писать не только id = 1.

Можно использовать те же условия, что и в обычном SELECT:

UPDATE users
SET promo_code = 'WELCOME10'
WHERE country = 'Russia' AND tier = 'free';

Этот запрос выдаст промокод всем пользователям из России на бесплатном тарифе.

Другой пример:

UPDATE orders
SET status = 'archived'
WHERE created_at < NOW() - INTERVAL '1 year';

Здесь мы архивируем старые заказы, созданные больше года назад.

Можно использовать:

  • AND;
  • OR;
  • NOT;
  • IN;
  • BETWEEN;
  • LIKE;
  • сравнения >, <, >=, <=;
  • проверки на NULL.

Например:

UPDATE users
SET email_confirmed = FALSE
WHERE email IS NULL;

WHERE — это фильтр. Чем точнее фильтр, тем безопаснее обновление.

SET может использовать старое значение

В SET можно не только записывать готовое значение, но и считать новое значение на основе старого.

Например, поднять цену всех товаров на 10%:

UPDATE products
SET price = price * 1.10;

Здесь новое значение price считается из старого price.

Было 1000, стало 1100.
Было 500, стало 550.

Другой пример: начислить пользователю 5 баллов.

UPDATE users
SET points = points + 5
WHERE id = 42;

Это очень важный приём.

Не нужно сначала читать значение в приложении, потом считать новое и записывать обратно. Часто лучше поручить вычисление самой базе.

Почему арифметику лучше делать прямо в UPDATE

Представь банковский счёт.

Плохой подход в приложении:

  1. Прочитали баланс.
  2. В коде посчитали новый баланс.
  3. Записали новое значение.

Например:

SELECT balance
FROM accounts
WHERE id = 1;

Приложение получило 100, посчитало 100 - 30 = 70, потом записало:

UPDATE accounts
SET balance = 70
WHERE id = 1;

Проблема в том, что между чтением и записью мог вмешаться другой процесс. Например, кто-то уже снял деньги или пополнил счёт. Тогда старое значение из приложения может перетереть более свежие данные.

Лучше делать так:

UPDATE accounts
SET balance = balance - 30
WHERE id = 1 AND balance >= 30;

Здесь база сама берёт текущий баланс и уменьшает его на 30 в одной операции.

Дополнительное условие balance >= 30 защищает от ухода в минус.

Если денег недостаточно, строка просто не обновится.

UPDATE с проверкой результата

Для денежных операций, остатков товаров и бонусов часто важно понять: обновилась строка или нет.

Например:

UPDATE accounts
SET balance = balance - 30
WHERE id = 1 AND balance >= 30
RETURNING id, balance;

Если строка вернулась — списание прошло.

Если строка не вернулась — либо счёта нет, либо денег недостаточно.

Такой подход часто надёжнее, чем сначала делать отдельный SELECT, а потом отдельный UPDATE.

Обновление по NULL

С NULL в SQL всегда нужно быть аккуратным.

Если нужно найти строки, где значение отсутствует, нельзя писать так:

UPDATE users
SET email_confirmed = FALSE
WHERE email = NULL;

Такой запрос не сработает как ожидается.

Для NULL используют IS NULL:

UPDATE users
SET email_confirmed = FALSE
WHERE email IS NULL;

А если нужно обновить строки, где значение есть:

UPDATE users
SET email_confirmed = TRUE
WHERE email IS NOT NULL;

Запомни: NULL — это не обычное значение. Это «значения нет». Поэтому сравнения через = здесь не подходят.

Обновление строк по списку значений

Иногда нужно обновить несколько конкретных строк.

Например, перевести несколько заказов в статус cancelled.

UPDATE orders
SET status = 'cancelled'
WHERE id IN (101, 102, 103);

IN удобен, когда есть список конкретных значений.

То же самое можно было бы написать через несколько OR, но получилось бы длиннее:

UPDATE orders
SET status = 'cancelled'
WHERE id = 101 OR id = 102 OR id = 103;

Для новичка IN обычно читается проще: обнови строки, где id входит в этот список.

Обновление по шаблону через LIKE

Можно обновлять строки, где текст подходит под шаблон.

Например, пометить тестовых пользователей:

UPDATE users
SET is_test = TRUE
WHERE email LIKE '%@test.com';

Здесь % означает «любое количество любых символов».

То есть условие найдёт email вроде:

email
anna@test.com
qa_user@test.com
demo@test.com

Но с такими запросами нужно быть осторожным. Шаблон может оказаться шире, чем ты думаешь. Перед обновлением лучше сделать SELECT с тем же условием.

SELECT
  id,
  email
FROM users
WHERE email LIKE '%@test.com';

Сначала посмотрели, потом обновили.

UPDATE меняет данные, но не структуру таблицы

Важно не путать:

UPDATE меняет значения в строках.

Он не создаёт новые колонки, не удаляет старые и не меняет типы данных.

Например, такой запрос меняет значение:

UPDATE users
SET name = 'Anna'
WHERE id = 1;

А если нужно добавить новую колонку, это уже не UPDATE, а ALTER TABLE.

ALTER TABLE users
ADD COLUMN middle_name TEXT;

Простая разница:

Команда Что делает
UPDATE Меняет данные в строках
INSERT Добавляет новые строки
DELETE Удаляет строки
ALTER TABLE Меняет структуру таблицы

UPDATE и ограничения таблицы

База данных не даст записать что угодно, если на таблице есть ограничения.

Например, если колонка email не может быть пустой, такой запрос может упасть:

UPDATE users
SET email = NULL
WHERE id = 1;

Если на колонке price стоит проверка, что цена должна быть больше нуля, такой запрос тоже может не пройти:

UPDATE products
SET price = -100
WHERE id = 10;

Это хорошо. Ограничения защищают таблицу от плохих данных.

UPDATE пытается изменить строку, но база всё равно проверяет правила: типы данных, NOT NULL, уникальность, внешние ключи, CHECK-ограничения.

Частые ошибки новичков

Забыли WHERE

Самая опасная ошибка:

UPDATE users
SET tier = 'gold';

Такой запрос обновит всех пользователей.

Правильнее:

UPDATE users
SET tier = 'gold'
WHERE id = 1;

Хорошая привычка: как только начал писать UPDATE, сразу подумай про WHERE.

Написали слишком широкое условие

Иногда WHERE есть, но он слишком общий.

Например:

UPDATE users
SET promo_code = 'WELCOME10'
WHERE country = 'Russia';

Может быть, ты хотел обновить только новых пользователей из России, а обновил вообще всех.

Точнее:

UPDATE users
SET promo_code = 'WELCOME10'
WHERE country = 'Russia' AND tier = 'free';

Перед массовым обновлением всегда полезно сделать проверочный SELECT.

Перепутали одинарные и двойные кавычки

Строки в SQL пишутся в одинарных кавычках.

Правильно:

UPDATE users
SET name = 'Anna'
WHERE id = 1;

В PostgreSQL двойные кавычки используются для имён таблиц и колонок.

Неправильно:

UPDATE users
SET name = "Anna"
WHERE id = 1;

База может решить, что "Anna" — это имя колонки, а не строка.

Забыли запятые в SET

Если обновляешь несколько колонок, между ними нужны запятые.

Неправильно:

UPDATE users
SET
  tier = 'gold'
  is_verified = TRUE
WHERE id = 1;

Правильно:

UPDATE users
SET
  tier = 'gold',
  is_verified = TRUE
WHERE id = 1;

Используют = NULL

Неправильно:

UPDATE users
SET email_confirmed = FALSE
WHERE email = NULL;

Правильно:

UPDATE users
SET email_confirmed = FALSE
WHERE email IS NULL;

Для NULL нужны IS NULL и IS NOT NULL.

Считают новое значение в приложении

Опасный подход:

SELECT points
FROM users
WHERE id = 1;

Потом приложение считает новое значение и пишет:

UPDATE users
SET points = 150
WHERE id = 1;

Если параллельно кто-то уже изменил points, можно перетереть чужое изменение.

Лучше:

UPDATE users
SET points = points + 10
WHERE id = 1;

База сама возьмёт текущее значение и обновит его.

Путаются в AND и OR

Сложные условия лучше писать со скобками.

Например:

UPDATE users
SET bonus = 100
WHERE (country = 'Russia' AND tier = 'gold')
   OR (country = 'Kazakhstan' AND tier = 'gold');

Без скобок запрос может читаться не так очевидно. SQL знает приоритеты операторов, но человек легко ошибается.

Скобки делают намерение понятным.

Безопасный алгоритм для UPDATE

Вот простой порядок действий, который стоит запомнить:

  1. Сначала напиши SELECT с нужным WHERE.
  2. Проверь, какие строки он возвращает.
  3. Убедись, что строк ровно столько, сколько ты ожидаешь.
  4. Напиши UPDATE с тем же WHERE.
  5. Если запрос важный, используй транзакцию.
  6. После обновления проверь результат.
  7. В PostgreSQL по возможности используй RETURNING.

Например:

SELECT
  id,
  email,
  tier
FROM users
WHERE email = 'anya@example.com';

Проверили. Теперь обновляем:

UPDATE users
SET tier = 'gold'
WHERE email = 'anya@example.com'
RETURNING id, email, tier;

Так работать спокойнее.

Короткая шпаргалка

Часть запроса За что отвечает
UPDATE users Какую таблицу обновляем
SET tier = 'gold' Какую колонку и на что меняем
WHERE id = 1 Какие строки обновляем
RETURNING id, tier Что показать после обновления

Пример целиком:

UPDATE users
SET
  tier = 'gold',
  upgraded_at = NOW()
WHERE id = 1
RETURNING id, tier, upgraded_at;

Мини-резюме

UPDATE — команда для изменения данных в уже существующих строках.

Она не добавляет строки и не удаляет их, а меняет значения в выбранных колонках.

Главные части запроса:

  • UPDATE — какую таблицу обновляем;
  • SET — какие колонки меняем;
  • WHERE — какие строки попадают под обновление.

Самое важное правило: не забывай WHERE. Без него обновятся все строки таблицы.

Перед важным обновлением сначала сделай SELECT с тем же условием. Так ты увидишь, какие строки будут затронуты.

Если меняешь деньги, баллы, остатки товаров или любые счётчики, лучше считать новое значение прямо в SQL:

UPDATE users
SET points = points + 5
WHERE id = 1;

Так база обновит текущее значение аккуратно и за одну операцию.

UPDATE — мощная команда. Она делает ровно то, что ты написал. Поэтому хороший SQL-разработчик пишет обновления спокойно, внимательно и всегда проверяет условие.

Закрепи на практике

Решай задачи в SQL-тренажёре с мгновенной проверкой и подсказками.

Открыть тренажёр