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.
Аня купила платный тариф. Нужно поменять её тариф с free на gold.
UPDATE users
SET tier = 'gold'
WHERE id = 1;
После запроса таблица станет такой:
Что важно заметить:
- изменилась только одна строка;
- изменилась только одна колонка;
- остальные данные Ани остались прежними;
- Боб и Вера не изменились, потому что их не пропустило условие
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;
Это простая привычка, которая спасает от многих неприятностей.
Особенно на рабочей базе.
Схема такая:
- Написал
SELECT с нужным WHERE.
- Проверил строки глазами.
- Убедился, что всё правильно.
- Выполнил
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
Представь банковский счёт.
Плохой подход в приложении:
- Прочитали баланс.
- В коде посчитали новый баланс.
- Записали новое значение.
Например:
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 вроде:
Но с такими запросами нужно быть осторожным. Шаблон может оказаться шире, чем ты думаешь. Перед обновлением лучше сделать 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
Вот простой порядок действий, который стоит запомнить:
- Сначала напиши
SELECT с нужным WHERE.
- Проверь, какие строки он возвращает.
- Убедись, что строк ровно столько, сколько ты ожидаешь.
- Напиши
UPDATE с тем же WHERE.
- Если запрос важный, используй транзакцию.
- После обновления проверь результат.
- В 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-разработчик пишет обновления спокойно, внимательно и всегда проверяет условие.
UPDATE— это команда, которая изменяет данные в уже существующих строках.Не добавляет новые строки — для этого есть
INSERT.Не удаляет строки — для этого есть
DELETE.А именно исправляет то, что уже лежит в таблице.
Представь таблицу как блокнот с контактами.
INSERT— это добавить нового человека.DELETE— вычеркнуть человека из блокнота.А
UPDATE— аккуратно заменить старый номер телефона на новый, потому что человек переехал или сменил SIM-карту.В SQL это одна из самых важных команд. И одновременно одна из тех, с которыми нужно быть особенно внимательным:
UPDATEдействительно меняет данные.Зачем нужен UPDATE
Данные в реальной жизни постоянно меняются.
Пользователь сменил email.
Заказ оплатили.
Товар подорожал.
Сотруднику повысили зарплату.
Статью перевели из черновика в опубликованное состояние.
Клиент накопил бонусные баллы.
Во всех этих случаях строка уже есть в таблице. Нужно просто поменять одно или несколько полей.
Например:
is_verifiedstatuspricetierpublished_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.Аня купила платный тариф. Нужно поменять её тариф с
freeнаgold.UPDATE users SET tier = 'gold' WHERE id = 1;После запроса таблица станет такой:
Что важно заметить:
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;Это простая привычка, которая спасает от многих неприятностей.
Особенно на рабочей базе.
Схема такая:
SELECTс нужнымWHERE.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обычно видно, сколько строк обновилось. Например:Это значит: обновлена одна строка.
Если ты ожидал одну строку, а увидел:
лучше остановиться и разобраться. Возможно, условие оказалось слишком широким.
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
Представь банковский счёт.
Плохой подход в приложении:
Например:
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 вроде:
Но с такими запросами нужно быть осторожным. Шаблон может оказаться шире, чем ты думаешь. Перед обновлением лучше сделать
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;Простая разница:
UPDATEINSERTDELETEALTER TABLEUPDATE и ограничения таблицы
База данных не даст записать что угодно, если на таблице есть ограничения.
Например, если колонка
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
Вот простой порядок действий, который стоит запомнить:
SELECTс нужнымWHERE.UPDATEс тем жеWHERE.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 usersSET tier = 'gold'WHERE id = 1RETURNING 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-разработчик пишет обновления спокойно, внимательно и всегда проверяет условие.