INSERT, UPDATE, DELETE без потери данных

SELECT учит задавать вопросы к данным. INSERT, UPDATE и DELETE уже меняют данные. Поэтому здесь другой уровень ответственности

Ошибиться в SELECT неприятно, но обычно безопасно: запрос просто вернул не то. Ошибиться в UPDATE без WHERE — это уже изменить все строки таблицы. Ошибиться в DELETE без проверки — удалить данные, которые потом придется доставать из бэкапа, если он вообще есть

В этом уроке сделаем все руками на маленькой таблице заказов: добавим запись, обновим статус, удалим тестовую строку и соберем привычку, которая спасает базы: сначала SELECT, потом изменение

Что получится в конце

Мы напишем безопасную последовательность:

SELECT *
FROM orders
WHERE id = 3;

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

SELECT *
FROM orders
WHERE id = 3;

И такую же проверку для удаления:

SELECT *
FROM orders
WHERE status = 'cancelled';

DELETE FROM orders
WHERE status = 'cancelled';

Главная мысль: запрос на изменение должен быть настолько точным, чтобы ты заранее видел, какие строки он затронет

Готовим таблицу

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer TEXT,
  product TEXT,
  amount INTEGER,
  status TEXT
);

Добавим стартовые данные:

INSERT INTO orders (id, customer, product, amount, status) VALUES
(1, 'Анна', 'Курс по SQL', 7900, 'paid'),
(2, 'Игорь', 'Консультация', 4500, 'paid'),
(3, 'Мария', 'Подписка', 1200, 'pending'),
(4, 'Олег', 'Настройка сайта', 15000, 'paid');

Проверим:

SELECT *
FROM orders
ORDER BY id;

INSERT INTO: добавляем строку

INSERT INTO добавляет новые данные

INSERT INTO orders (id, customer, product, amount, status)
VALUES (5, 'Светлана', 'Шаблон лендинга', 3900, 'pending');

После добавления проверяем:

SELECT *
FROM orders
WHERE id = 5;

Я почти всегда указываю список колонок:

INSERT INTO orders (id, customer, product, amount, status)

Так запрос не зависит от порядка столбцов в таблице. Если позже кто-то добавит колонку created_at, явный список колонок поможет не сломать вставку

INSERT нескольких строк

Можно добавить несколько строк одним запросом:

INSERT INTO orders (id, customer, product, amount, status) VALUES
(6, 'Денис', 'Аудит сайта', 11000, 'paid'),
(7, 'Елена', 'Подписка', 1200, 'pending'),
(8, 'Павел', 'Консультация', 4500, 'cancelled');

Проверяем:

SELECT *
FROM orders
WHERE id IN (6, 7, 8)
ORDER BY id;

Для учебы это кажется лишним шагом, но в настоящей базе привычка проверять результат сразу после изменения очень быстро окупается

UPDATE: меняем существующие строки

Мария оплатила подписку. Нужно поменять статус заказа id = 3 с pending на paid

Сначала смотрим строку:

SELECT *
FROM orders
WHERE id = 3;

Потом обновляем:

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

И проверяем:

SELECT *
FROM orders
WHERE id = 3;

Обрати внимание на WHERE. Без него запрос станет опасным:

UPDATE orders
SET status = 'paid';

Такой запрос изменит статус у всех заказов. Иногда это действительно нужно, но новичку стоит относиться к такому запросу как к красной кнопке

UPDATE нескольких колонок

Можно изменить сразу несколько полей:

UPDATE orders
SET
  amount = 1500,
  status = 'paid'
WHERE id = 3;

Перед этим снова полезно сделать SELECT:

SELECT id, customer, amount, status
FROM orders
WHERE id = 3;

Проверяем не "примерно эту строку", а точное условие, которое пойдет в UPDATE

DELETE: удаляем строки

Представим, что хотим удалить отмененные заказы из учебной таблицы

Сначала смотрим, что попадет под удаление:

SELECT *
FROM orders
WHERE status = 'cancelled';

Если результат именно тот, который нужен, удаляем:

DELETE FROM orders
WHERE status = 'cancelled';

Проверяем:

SELECT *
FROM orders
WHERE status = 'cancelled';

DELETE без WHERE удалит все строки:

DELETE FROM orders;

Это не удалит саму таблицу, но очистит ее содержимое. Если хочешь удалить таблицу целиком, это уже другой оператор:

DROP TABLE orders;

А удалить базу данных — еще более опасная операция:

DROP DATABASE database_name;

В учебных материалах важно прямо сказать: такие команды нельзя выполнять на рабочей базе "для проверки". Только на тестовой базе, копии или после согласованного бэкапа

Транзакция: страховка перед изменением

Во многих базах можно завернуть изменение в транзакцию:

BEGIN TRANSACTION;

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

SELECT *
FROM orders
WHERE id = 7;

ROLLBACK;

ROLLBACK откатывает изменение. Если все хорошо, вместо него используют:

COMMIT;

Синтаксис транзакций может немного отличаться в SQL Server, MySQL, PostgreSQL и SQLite, но идея одинаковая: начать изменение, проверить, подтвердить или откатить

Для первых упражнений online-редактор может не поддерживать транзакции так, как локальная база. Поэтому не удивляйся, если пример нужно адаптировать под конкретный сервис

Безопасный чеклист перед UPDATE и DELETE

Перед изменением я бы проходил такой список:

  1. Я понимаю, какую таблицу меняю.
  2. Я написал SELECT с тем же WHERE.
  3. Результат SELECT показывает ровно те строки, которые нужно изменить.
  4. В запросе есть точное условие.
  5. Я работаю не на единственной копии важных данных.
  6. Для массового изменения есть транзакция или бэкап.

Это звучит медленно. На практике это быстрее, чем потом объяснять, почему все пользователи внезапно стали paid

Частые ошибки

Забыли WHERE

UPDATE orders
SET status = 'cancelled';

Так обновятся все строки. Перед выполнением проверь, есть ли WHERE, и действительно ли оно ограничивает нужные строки

Слишком широкое условие

DELETE FROM orders
WHERE amount < 5000;

Может казаться, что удаляем "мелкие тестовые заказы", но под условие попадут реальные оплаченные заказы на 4500. Лучше сначала:

SELECT *
FROM orders
WHERE amount < 5000;

Перепутали DELETE и DROP

DELETE удаляет строки из таблицы. DROP TABLE удаляет таблицу. DROP DATABASE удаляет базу. Это разные уровни разрушения

Вставили значения не в том порядке

Так опаснее:

INSERT INTO orders
VALUES (9, 'Никита', 'paid', 5000, 'Консультация');

Если порядок колонок другой, данные разъедутся. Лучше явно:

INSERT INTO orders (id, customer, product, amount, status)
VALUES (9, 'Никита', 'Консультация', 5000, 'paid');

Мини-задания

  1. Добавь новый заказ со статусом pending.
  2. Обнови его статус на paid.
  3. Измени сумму заказа.
  4. Найди все отмененные заказы через SELECT.
  5. Удали отмененные заказы после проверки.

Возможное решение:

INSERT INTO orders (id, customer, product, amount, status)
VALUES (10, 'Кирилл', 'Мини-аудит', 2500, 'pending');

SELECT *
FROM orders
WHERE id = 10;

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

SELECT *
FROM orders
WHERE id = 10;

Ответы на эти вопросы могут быть для вас полезными

Что делает INSERT INTO в SQL?

INSERT INTO добавляет новые строки в таблицу. Лучше всегда указывать список колонок, чтобы не зависеть от их порядка

Как безопасно делать UPDATE?

Сначала напиши SELECT с тем же условием WHERE, проверь строки, потом выполняй UPDATE. Для важных данных используй транзакцию или работай на копии

Что будет, если выполнить DELETE без WHERE?

Из таблицы будут удалены все строки. Таблица останется, но данные исчезнут. На рабочей базе это может быть критичной ошибкой

DELETE и DROP TABLE — это одно и то же?

Нет. DELETE удаляет строки. DROP TABLE удаляет саму таблицу. DROP DATABASE удаляет базу данных

Нужно ли учить транзакции новичку?

Да, хотя бы на базовом уровне. Транзакции помогают понять, как безопасно подтверждать или откатывать изменения

Что почитать дальше по SQL

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

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x