Забытый WHERE
Что будет, если в UPDATE нет WHERE? Он изменит каждую строку таблицы. Эта инструкция должна была переселить одного клиента в London:
UPDATE customers
SET city = 'London';На вкладке «Результаты» написано Изменено строк: 14: все клиенты магазина теперь живут в London, а их настоящие города потеряны:
| name | city |
|---|---|
| Emma Clark | London |
| Liam Turner | London |
| Olivia Brown | London |
| … | … |
База данных не спрашивает, уверены ли вы, и кнопки «Отменить» нет. То же самое с DELETE, о котором вы узнаете в следующем упражнении: без WHERE он удаляет все строки таблицы. Это одна из самых известных ошибок в программировании, и она случается даже с опытными программистами, обычно когда они запускают инструкцию, не дописав её. Здесь следующий запуск вернёт данные. В настоящей базе вернуться можно только из резервной копии, если она есть.
Как себя защитить:
- Сначала напишите
WHEREи проверьте его запросомSELECT. Прежде чем менять строки, посмотрите на них: запрос с тем жеWHEREпоказывает ровно те строки, которых коснётся изменение. Когда он находит нужные, превратитеSELECT … FROM customersвUPDATE customers SET …, аWHEREоставьте как есть. - Проверяйте «Изменено строк». Если вы хотели изменить одного клиента, там должно быть 1. Если там 14, что-то не так.
- Используйте транзакцию, которая умеет отменять изменения. О транзакциях вы узнаете в конце этого урока.
Например, у Leo Walker новый адрес электронной почты. Сначала запрос:
SELECT id, name, email
FROM customers
WHERE id = 8;| id | name | |
|---|---|---|
| 8 | Leo Walker | leo.walker@mail.com |
Он находит одну строку, нужную, поэтому его WHERE можно без изменений перенести в UPDATE:
UPDATE customers
SET email = 'leo@walker.uk'
WHERE id = 8;WHERE может найти и не те строки, которые вы имели в виду: больше (AND выполняется раньше OR, а LIKE '%an%' находит больше имён, чем вы ожидаете) или ни одной (= NULL не находит ничего). SELECT с тем же WHERE покажет всё это до того, как будет нанесён вред.
Задание
- 1
Запустите файл. В первом
UPDATEнетWHERE: на вкладке «Результаты» написаноИзменено строк: 30, а первый запрос показывает все заказы как возвращённые. Прежде чем исправлять, найдите строку, которую он должен изменить: в самом начале файла напишите запрос, который показывает ID, клиента и дату заказов клиента 3 от 2025-03-03. Он должен найти ровно один:id customer_id ordered_at 17 3 2025-03-03 - 2
Теперь добавьте этот
WHEREв первыйUPDATE. Он изменит 1 строку, и первый запрос в конце покажет только три возвращённых заказа:id customer_id ordered_at status 7 6 2024-06-01 refunded 17 3 2025-03-03 refunded 18 8 2025-03-28 refunded - 3
Второй
UPDATEдолжен снизить цены игр Action и RPG, которые стоят дороже $35, а таких три, но он меняет 6 строк. Проверьте егоWHEREзапросом, выясните, почему он находит больше игр, и исправьте его. Тогда последний запрос должен показать:title genre price Robot Rebellion Action 35 Shadow Ninja Action 25 Star Pilots Action 35 Zombie Town Action 30 Dragon Forge RPG 35 Knight's Oath RPG 55