Ir al contenido
wannacode

La panadería, etapa 2: los datos

En resumen: La etapa 2 llena las tablas de la panadería con INSERT, RETURNING e INSERT … SELECT, y guarda el primer pedido dentro de una transacción.

Problema

Tablas vacías

Las tablas de la etapa 1 están listas y vacías. La panadería tiene tres categorías, ocho productos, cinco clientes y sus primeros pedidos. En esta etapa los escribes, y cada regla de la etapa 1 vigilará los datos.

Todos los campos parten de la base que has construido hasta ahora: las cinco tablas y los datos de los pasos anteriores de la etapa.

La idea

La primera fila

INSERT INTO tabla (columnas) VALUES (valores) escribe una fila. La columna id no está en la lista: INTEGER PRIMARY KEY sin valor recibe por sí sola el siguiente número.

SQLbase de datos vacía

Las columnas entre paréntesis importan. INSERT INTO categories VALUES (1, 'Pan') también funciona, pero depende del orden de las columnas de la tabla y se rompe con la primera columna nueva.

Pruébalo

Las tres categorías

Escribe las tres categorías con un solo INSERT: Pan, Dulces y Bebidas, en este orden (Pan es 1, Dulces 2, Bebidas 3).

SQLbase de datos vacía

La idea

Lo que escribió la base

El programa a menudo necesita el número de la fila nueva, por ejemplo para mostrar «El producto se añadió con el número 1». RETURNING devuelve las columnas de la fila escrita:

SQLbase de datos vacía

RETURNING también devuelve los valores que la base puso por sí sola: sin stock en la lista devolvería 0, que viene de DEFAULT. Los ocho productos se escriben con un solo INSERT:

SQLbase de datos vacía
Más precisamente, para curiosos

RETURNING existe en SQLite desde la versión 3.35 y en PostgreSQL. MySQL no lo tiene: allí el número se toma con LAST_INSERT_ID(), y en SQLite también con last_insert_rowid().

Míralo

Las reglas vigilan

Las reglas de la etapa 1 ya funcionan. Un producto con precio 0:

SQLbase de datos vacía

Un producto en la categoría 9, que no existe:

SQLbase de datos vacía

Un producto sin nombre:

SQLbase de datos vacía

Ninguno de los tres entra. El error viene de la base, así que da igual quién envíe la fila: el sitio, un script de importación desde Excel o un compañero en la consola.

Pruébalo

Los clientes

Escribe los cinco clientes con un solo INSERT (columnas name, email, city): Ivan Kolev, ivan.kolev@example.com, Sofía; Ana Petrova, ana.petrova@example.com, Plovdiv; Boris Nikolov, boris.nikolov@example.com, Sofía; Desislava Marinova, desislava.marinova@example.com, Varna; Kalin Todorov, kalin.todorov@example.com, sin ciudad.

SQLbase de datos vacía
Más precisamente, para curiosos

UNIQUE compara el texto letra por letra: Ivan.Kolev@example.com e ivan.kolev@example.com son dos correos distintos para la base. Por eso el programa pasa el correo a minúsculas antes de escribirlo, o la tabla mantiene UNIQUE sobre lower(email) con un índice (CREATE UNIQUE INDEX … ON customers (lower(email))).

Míralo

El mismo correo

SQLbase de datos vacía

Ivan de Plovdiv es otra persona con el mismo correo, y la base no lo deja entrar. El registro en el sitio muestra justo este error como «Este correo ya está registrado».

La idea

El pedido y sus líneas

Un pedido sin status recibe 'new' de DEFAULT:

SQLbase de datos vacía

Un pedido real, sin embargo, son dos tipos de filas: una en orders y varias en order_items. Si el programa se cae entre ambas, queda un pedido sin un solo producto. Por eso las dos se escriben en una transacción: BEGIN, los insert, COMMIT. Hasta el COMMIT nada es definitivo.

Pruébalo

El primer pedido

Ivan (cliente 1) pidió el 2026-10-01 dos panes de campo (producto 1 a 2,40) y tres cruasanes (producto 4 a 1,30). El pedido está entregado. Escríbelo en una transacción: el pedido (tendrá el número 1) y sus dos líneas.

SQLbase de datos vacía

Míralo

Cancelar

El programa ha escrito el pedido y descubre que algo va mal (la tarjeta fue rechazada, una línea se detuvo con un error). Entonces, en lugar de COMMIT, envía ROLLBACK:

SQLbase de datos vacía

Durante la transacción hay 2 pedidos, y después del ROLLBACK otra vez 1: el segundo desapareció, como si el INSERT nunca hubiera existido.

Más precisamente, para curiosos

Aquí cada campo se detiene en el primer error, como la consola. El programa hace lo mismo con try: ante una excepción envía ROLLBACK. La transacción no se cancela sola cuando falla una consulta, así que el ROLLBACK es cosa del programa.

Míralo

Los otros pedidos

Los pedidos del 2 al 6 se escriben igual. Aquí están, con el número de pedidos por estado al final:

SQLbase de datos vacía

El pedido 4 está cancelado, el 5 está pagado y espera la entrega, y el 6 es nuevo. Kalin (cliente 5) todavía no ha pedido.

Ejercicio

El precio del producto

El sitio no se sabe los precios de memoria. Cuando el cliente compra, el precio se toma de products en ese momento y se escribe en la línea. INSERT … SELECT escribe las filas que devuelve un SELECT.

Kalin (cliente 5) pide hoy dos baguettes (producto 3). Escribe el pedido (será el número 7, la fecha es date('now')) y su línea, tomando unit_price de products con INSERT … SELECT.

SQLbase de datos vacía

La idea

La base completa

Los seis pedidos están en la base. Cuántas filas tiene cada tabla:

SQLbase de datos vacía

La siguiente etapa hace preguntas a estos datos: la carta, la cuenta de cada pedido, quién compra qué.

Test

Ponte a prueba

1. En INSERT INTO categories (name) VALUES (…) no hay id. ¿De dónde sale?
2. El pedido entró y su línea se detuvo con un error. ¿Qué hace el programa?
3. ¿Por qué el precio de la nueva línea del pedido se toma con SELECT … FROM products y no se escribe a mano como 1,60?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·