Изменение данных: INSERT, UPDATE и DELETE
Курс MS SQL с нуля · Урок 7 из 12 · Часть 3. Изменение и проектирование
До этого урока курс только читал базу. Теперь мы пишем: три оператора изменения, предложение OUTPUT и первое правило выживания — любой массовый UPDATE или DELETE сначала прогоняется как SELECT с тем же WHERE.
Внимание: урок меняет данные TechStore. После занятия база обязательно восстанавливается повторным прогоном скриптов урока 2 — иначе съедут числа всех следующих уроков.
Содержание
1. Что вы освоите
К концу урока вы:
- добавляете строки с явным списком столбцов и читаете IDENTITY корректно;
- меняете множества строк с прогнозом и постпроверкой числа затронутых;
- читаете старые и новые значения через OUTPUT;
- удаляете только после «корзинного» SELECT;
- отличаете TRUNCATE от DELETE и знаете цену каждого.
2. INSERT и номер новой строки
Чистый код
INSERT dbo.Customers (FullName, Email, City, RegisteredAt)
VALUES (N'Giovanni Papadopoulos', Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ', N'Рим', SYSDATETIME());
SELECT SCOPE_IDENTITY() AS new_customer_id;
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
INSERT dbo.Customers (FullName, Email, City, RegisteredAt) -- → перечень столбцов обязателен: значения лягут точно по нему VALUES (N'Giovanni Papadopoulos',Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ', N'Рим', SYSDATETIME()); -- → сегмент не указан: сработает его дефолт Retail SELECT SCOPE_IDENTITY() AS new_customer_id; -- → номер нового ключа, присвоенный именно этому оператору, не соседнемуSQL
- список столбцов обязателен всегда — даже когда совпадает с порядком таблицы: добавление нового столбца тогда ничего не ломает;
- IDENTITY-столбец в списке не упоминается: значение назначает сервер;
- для массовых вставок INSERT берёт строки из SELECT — базовый инструмент копий и снимков.
3. UPDATE: безопасная анатомия
UPDATE меняет множество строк за один оператор; предикат WHERE — его тормоз. Анатомия безопасного изменения — тройка операторов:
- SELECT тем же WHERE: число строк глазами сверяется с ожиданием;
- UPDATE с тем же WHERE и OUTPUT для осмотра старых и новых значений;
- постпроверка итоговым SELECT: три числа обязаны совпасть.
Чистый код
SELECT COUNT(*) AS moscow_cnt FROM dbo.Customers AS c WHERE c.City = N'Москва';
GO
UPDATE c SET City = N'Москва (МО)'
OUTPUT deleted.CustomerID, deleted.City AS old_city, inserted.City AS new_city
FROM dbo.Customers AS c
WHERE c.City = N'Москва';
GO
SELECT COUNT(*) AS renamed_cnt FROM dbo.Customers AS c WHERE c.City = N'Москва (МО)';
GO
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
SELECT COUNT(*) AS moscow_cnt FROM dbo.Customers AS c WHERE c.City = N'Москва'; -- → прогноз: сколько строк сейчас под предикатом; число запоминается GO UPDATE c SET City = N'Москва (МО)' -- → изменение под тем же предикатом OUTPUT deleted.CustomerID, deleted.City AS old_city, inserted.City AS new_city -- → осмотр: старое и новое значение каждой затронутой строки FROM dbo.Customers AS c WHERE c.City = N'Москва'; GO SELECT COUNT(*) AS renamed_cnt FROM dbo.Customers AS c WHERE c.City = N'Москва (МО)'; -- → постпроверка: счётчик обязан равняться прогнозу GOSQL
OUTPUT: чтение изменённого в том же операторе
Виртуальные таблицы inserted и deleted доступны прямо в UPDATE, DELETE и INSERT: deleted хранит старые значения, inserted — новые. Это опора аудита в продвинутом курсе; здесь важно увидеть вывод руками и понять, что «повторным запросом» старое значение не восстановить по памяти уже нельзя.
↑ К оглавлению4. DELETE, корзина и TRUNCATE
DELETE удаляет строки по фильтру и журналирует каждую построчно; TRUNCATE опустошает таблицу целиком, быстро и без деталей, но запрещён на таблицах с внешними ключами. В курсе используется DELETE с предварительным SELECT «на корзину»:
Чистый код
SELECT COUNT(*) AS target_cnt FROM dbo.Customers AS c
WHERE c.Email = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ';
DELETE c FROM dbo.Customers AS c
WHERE c.Email = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ';
SELECT COUNT(*) AS target_after FROM dbo.Customers AS c
WHERE c.Email = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ';
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
SELECT COUNT(*) AS target_cnt FROM dbo.Customers AS c WHERE c.Email =Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. '; -- → прицел подтверждён: ожидается ровно одна строка DELETE c FROM dbo.Customers AS c WHERE c.Email =Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. '; -- → удаление тем же предикатом SELECT COUNT(*) AS target_after FROM dbo.Customers AS c WHERE c.Email =Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. '; -- → постпроверка: ожидается нольSQL
5. Задачи и эталонные решения
Шесть задач на контексте TechStore. Регламент: урок меняет базу; после занятия она восстанавливается скриптами урока 2.
- новый клиент: вставка и номер через SCOPE_IDENTITY, проверка по номеру;
- наценка десять процентов на «Зарядные устройства»: номер категории находится по имени LIKE, SELECT-прогноз до UPDATE, OUTPUT первых строк;
- обнуление остатков и снятие активности у «Чехлов» одним UPDATE двух столбцов;
- удаление тестового клиента по корзинному паттерну, EXISTS-постпроверка;
- снимок цен активных товаров: создать dbo.PriceSnapshot и наполнить INSERT SELECT, сверить число строк с числом активных;
- переименование города Москвы по тройке «прогноз — изменение — постпроверка», шестьдесят процентов клиентов — серьёзная проверка тормозов.
Эталон безопасного UPDATE
тройка операторов последовательно
Чистый код
SELECT COUNT(*) AS rows_before
FROM dbo.Products AS p WHERE p.CategoryID = 10;
UPDATE p SET Price = Price * 1.10
OUTPUT TOP (5) deleted.ProductID, deleted.Price AS old_price,
inserted.Price AS new_price
FROM dbo.Products AS p
WHERE p.CategoryID = 10;
SELECT COUNT(*) AS rows_after
FROM dbo.Products AS p WHERE p.CategoryID = 10;
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
SELECT COUNT(*) AS rows_before FROM dbo.Products AS p WHERE p.CategoryID = 10; -- → категория 10, «Зарядные устройства»: прогноз числа строк UPDATE p SET Price = Price * 1.10 -- → наценка десяти процентов OUTPUT TOP (5) deleted.ProductID, deleted.Price AS old_price, inserted.Price AS new_price -- → осмотр первых пяти пар «было-стало» FROM dbo.Products AS p WHERE p.CategoryID = 10; SELECT COUNT(*) AS rows_after FROM dbo.Products AS p WHERE p.CategoryID = 10; -- → постпроверка: число совпадает с прогнозомзадача 7.2: изменение с прогнозом и осмотром
6. Типичные ошибки урока
- UPDATE без WHERE — изменена вся таблица; профилактика: курсор на WHERE до Ctrl+Enter и глаза на предикат.
- INSERT без списка столбцов — работает до первого добавленного столбца; список обязателен всегда.
- Номер прочитан @@IDENTITY — при триггере вернётся чужой номер; канон — SCOPE_IDENTITY.
- UPDATE без алиаса в соединении — эталоны курса всегда с алиасом и JOIN в FROM, иначе теряется контроль, какая таблица меняется.
- Msg 547 при DELETE — защита внешнего ключа; лечится цепочкой осознанных удалений, не снятием связи.
- TRUNCATE доверия ради — запрещён на связанных таблицах; выбор между ним и DELETE — осознанный, не «быстрее же».
7. Чек-лист практики и источники
Чек-лист урока 7
отметки делаются по факту
Источники для углубления:
- INSERT: синтаксис и варианты;
- OUTPUT: inserted и deleted;
- DELETE и ограничение внешнего ключа (Msg 547).
Проверено: 23.10.2026
↑ К оглавлению