Skip to content
wannacode

The bakery, stage 4: the changes

In short: Stage 4 changes the bakery data with UPDATE, DELETE and an upsert, and a delivered order lowers the stock inside a transaction.

Problem

Nothing stays put

Flour got dearer. Ana paid for her order. Desislava's order set off to her. Boris cancelled his. A delivery came. All of this is changing rows that already exist: UPDATE, DELETE and an insert that may also be a change.

Every field starts from the full database from stage 2.

The idea

SELECT first

The pastries get 10% dearer. Before the UPDATE you run a SELECT with the same WHERE and the new value as an expression. That way you see which rows will change and how:

SQLempty database

Three rows, only the pastries. Now the same WHERE goes into the UPDATE.

Try it

The price rise

Raise the prices of the pastries (category 2) by 10%, rounded to 2 places.

SQLempty database

See it

The old bill

The price of the croissant is now €1.43. Order 1, though, keeps the price at which Ivan bought:

SQLempty database

That is why in stage 1 order_items has unit_price: last week's bill does not change.

Try it

Paid

Ana paid for order 6. Change its status to 'paid'.

SQLempty database

A typo does not get through, because the CHECK from stage 1 guards the statuses:

SQLempty database

Exercise

The delivery

When the order is delivered, the products leave the store. For every product of the order the stock goes down by the pieces in the row. That is an UPDATE with a subquery that takes the pieces for each product.

Order 5 (Desislava's) is delivered. In one transaction lower the stock of every product in it by the pieces in the row and change the status of the order to 'delivered'.

SQLempty database
More precisely, if you are curious

SQLite since 3.33 and PostgreSQL also have UPDATE … FROM: UPDATE products SET stock = stock - i.quantity FROM order_items i WHERE i.order_id = 5 AND i.product_id = products.id;. The result is the same, and for many rows it is faster.

See it

More than there is

There are 10 kozunaks. Someone tries to sell 20:

SQLempty database

CHECK (stock >= 0) from stage 1 does not allow selling something that is not there.

The idea

Deleting

A product that is in orders cannot be deleted: the foreign key in order_items guards it.

SQLempty database

A product that is no longer sold stays in the database. Taking it off the menu is another column (active) or another category, not DELETE.

Try it

The cancelled order

The bakery does not keep cancelled orders. Delete order 4 together with its rows.

SQLempty database
More precisely, if you are curious

Many systems do not delete orders at all: the status 'cancelled' is enough, and the history stays for the reports and the accounts. This is called a soft delete. Here it is DELETE so that you see CASCADE at work.

Try it

A new delivery

A delivery came: 20 croissants (product 4, which already exists) and a new product, 25 bottles of boza (it will be product 9, a drink for €1.50). One and the same INSERT has to add the new one and increase the existing one. This is an upsert: INSERT … ON CONFLICT (id) DO UPDATE.

With one INSERT write the delivery: (4, 'Croissant', 2, 1.30, 20) and (9, 'Boza', 3, 1.50, 25). If the product exists, its stock grows by what was delivered.

SQLempty database

The idea

What comes next

Every change here is a query written by hand: the stock goes down when someone remembers. The next stage makes the database do it on its own and be faster: an index, a view, a trigger and a new column.

Test

Check yourself

1. What does UPDATE products SET price = price * 1.1 without WHERE do?
2. The croissant got dearer. What happens to the bill of order 1, where Ivan took three croissants?
3. A delivery of 20 croissants with INSERT OR REPLACE instead of ON CONFLICT … DO UPDATE. What happens to the stock?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·