Към съдържанието
wannacode

Пекарната, етап 4: промените

Накратко: Четвъртият етап променя данните на пекарната с UPDATE, DELETE и upsert, а доставената поръчка сваля наличността в транзакция.

Проблем

Нищо не стои на място

Брашното поскъпна. Ана плати поръчката си. Поръчката на Десислава тръгна към нея. Борис отказа своята. Дойде доставка. Всичко това е промяна на редове, които вече ги има: UPDATE, DELETE и вмъкване, което може да е и промяна.

Всяко поле тръгва от пълната база от етап 2.

Идеята

Първо SELECT

Сладкишите поскъпват с 10%. Преди UPDATE се пуска SELECT със същото WHERE и новата стойност като израз. Така се вижда кои редове ще се сменят и как:

SQLпразна база

Три реда, само сладкишите. Сега същото WHERE отива в UPDATE.

Пробвай

Поскъпването

Вдигни цените на сладкишите (категория 2) с 10%, закръглени до 2 знака.

SQLпразна база

Виж го

Старата сметка

Цената на кроасана вече е 1.43 €. Поръчка 1 обаче пази цената, на която Иван е купил:

SQLпразна база

Затова в етап 1 order_items има unit_price: сметката от миналата седмица не се променя.

Пробвай

Платено

Ана плати поръчка 6. Смени статуса ѝ на 'paid'.

SQLпразна база

Грешка в думата не минава, защото CHECK от етап 1 пази статусите:

SQLпразна база

Упражнение

Доставката

Когато поръчката е доставена, продуктите излизат от склада. За всеки продукт от поръчката наличността намалява с бройките в реда. Това е UPDATE с подзаявка, която за всеки продукт взима неговите бройки.

Поръчка 5 (на Десислава) е доставена. В една транзакция намали наличността на всеки продукт от нея с бройките в реда и смени статуса на поръчката на 'delivered'.

SQLпразна база
По-точно, за любопитните

SQLite от 3.33 и PostgreSQL имат и UPDATE … FROM: UPDATE products SET stock = stock - i.quantity FROM order_items i WHERE i.order_id = 5 AND i.product_id = products.id;. Резултатът е същият, а за много редове е по-бърз.

Виж го

Повече, отколкото има

Козунаците са 10. Някой се опитва да продаде 20:

SQLпразна база

CHECK (stock >= 0) от етап 1 не позволява продажба на нещо, което го няма.

Идеята

Изтриване

Продукт, който е в поръчки, не може да се изтрие: външният ключ в order_items го пази.

SQLпразна база

Продуктът, който вече не се продава, остава в базата. Махането му от менюто е друга колона (active) или друга категория, не DELETE.

Пробвай

Отказаната поръчка

Пекарната не пази отказаните поръчки. Изтрий поръчка 4 заедно с редовете ѝ.

SQLпразна база
По-точно, за любопитните

Много системи не трият поръчки изобщо: статусът 'cancelled' е достатъчен, а историята остава за отчетите и за счетоводството. Това се казва меко изтриване (soft delete). Тук DELETE е, за да се види CASCADE в действие.

Пробвай

Нова доставка

Дойде доставка: 20 кроасана (продукт 4, вече го има) и нов продукт, 25 бутилки боза (ще е продукт 9, напитка за 1.50 €). Един и същ INSERT трябва да добави новото и да увеличи наличното. Това е upsert: INSERT … ON CONFLICT (id) DO UPDATE.

С един INSERT запиши доставката: (4, 'Кроасан', 2, 1.30, 20) и (9, 'Боза', 3, 1.50, 25). Ако продуктът го има, наличността му се увеличава с доставеното.

SQLпразна база

Идеята

Какво следва

Всяка промяна тук е заявка, написана на ръка: наличността се сваля, когато някой се сети. Следващият етап кара базата да го прави сама и да е по-бърза: индекс, изглед, тригер и нова колона.

Тест

Провери се

1. Какво прави UPDATE products SET price = price * 1.1 без WHERE?
2. Кроасанът поскъпна. Какво става със сметката на поръчка 1, където Иван взе три кроасана?
3. Доставка на 20 кроасана с INSERT OR REPLACE вместо ON CONFLICT … DO UPDATE. Какво става с наличността?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·