Изменение и удаление таблиц
Таблицы со временем меняются: магазин начинает собирать новые данные или оказывается, что название непонятно. Не нужно удалять таблицу со всеми строками и создавать её заново: ALTER TABLE изменяет уже существующую таблицу. ADD COLUMN добавляет в неё столбец:
ALTER TABLE customers
ADD COLUMN phone TEXT;
SELECT name, phone
FROM customers
LIMIT 2;| name | phone |
|---|---|
| Emma Clark | NULL |
| Liam Turner | NULL |
Новый столбец добавляется в конец таблицы. В уже существующих строках в нём окажется NULL или значение столбца по умолчанию (DEFAULT). Поэтому новому столбцу с NOT NULL нужен DEFAULT: без него существующие строки нарушили бы правило:
ALTER TABLE customers
ADD COLUMN newsletter INTEGER NOT NULL;Error on line 1: Cannot add a NOT NULL column with default value NULLС DEFAULT 0 всё получится, и у каждого клиента будет 0. RENAME COLUMN переименовывает столбец, а RENAME TO — всю таблицу:
ALTER TABLE customers
RENAME COLUMN joined TO signed_up;
ALTER TABLE order_items
RENAME TO order_lines;SQLite меняет название везде в базе данных, например во внешних ключах других таблиц. Но запросы в коде приложения по-прежнему используют старое название и перестали бы работать, поэтому в настоящих приложениях таблицы и столбцы переименовывают редко и осторожно. Кроме этого, ALTER TABLE в SQLite умеет только удалять столбец (DROP COLUMN). Он не может изменить тип столбца или добавить NOT NULL, UNIQUE или CHECK к существующему столбцу. Для этого создают новую таблицу такой, какой она должна быть, копируют в неё строки с помощью INSERT … SELECT, удаляют старую таблицу и дают новой её имя. Другие базы данных умеют больше.
DROP TABLE reviews; удаляет таблицу со всеми строками. Вопроса «Вы уверены?» нет, и отменить удаление нельзя; только внутри транзакции ROLLBACK может вернуть таблицу. Таблицу, на которую указывают внешние ключи других таблиц, нельзя удалить, пока в них есть указывающие на неё строки, поэтому сначала нужно удалить таблицы, которые на неё указывают:
DROP TABLE games;Error on line 1: FOREIGN KEY constraint failedDROP TABLE для таблицы, которой нет, — ошибка, как и CREATE TABLE для таблицы, которая уже есть. В скриптах, которые могут запускаться больше одного раза, программисты пишут DROP TABLE IF EXISTS и CREATE TABLE IF NOT EXISTS: когда таблицы нет или она уже есть, инструкция просто ничего не делает. Вкладка «Таблицы» продолжает показывать таблицы в том виде, с каким начинается упражнение; ваши изменения видны только инструкциям вашего файла.
Типичная ошибка: путать DROP TABLE и DELETE FROM. DELETE FROM reviews; удаляет все строки, но пустая таблица остаётся, готовая к новым. DROP TABLE reviews; удаляет саму таблицу вместе со столбцами и правилами.
Задание
- 1
Магазин готовит распродажу. Добавьте в таблицу
gamesстолбецdiscount: целое число, всегда заполнено, по умолчанию 0. Затем назначьте гоночным играм (жанр Racing) скидку 5 (с помощьюUPDATE). Наконец, покажите название, жанр и скидку игр жанров Racing и Puzzle, отсортированные по названию:title genre discount Cube Logic Puzzle 0 Pixel Racer Racing 5 Turbo Karts Racing 5 Word Quest Puzzle 0 - 2
Ниже переименуйте таблицу
reviewsвgame_reviews, а её столбецstars— вrating. Затем покажите, сколько отзывов с каждой оценкой, в столбцахratingиreviews, начиная с самой высокой оценки:rating reviews 5 8 4 10 3 5 2 2 - 3
Теперь магазин принимает заказы через сервис онлайн-платежей, который хранит их в своей базе данных, так что в этой базе они больше не нужны. В конце файла удалите таблицы
ordersиorder_items. Напишите обе сIF EXISTS(DROP TABLE IF EXISTS …), чтобы файл работал и на базе данных, где их уже нет. Одна из двух таблиц указывает на другую: подумайте, какую из них нужно удалить первой.