INSERT: insertar filas
En resumen: INSERT INTO … VALUES inserta una fila, INSERT … SELECT inserta filas que vienen de una consulta, y las reglas de la tabla (UNIQUE, NOT NULL, CHECK, clave foránea) rechazan las filas incorrectas.
Problema
Un cliente nuevo
Hasta ahora solo has leído de la base de datos. Pero cada día entran cosas nuevas. Hoy se registró en el sitio web Vesela Raykova, de Pleven.
El sitio web tiene que escribir una fila nueva en customers. Nadie abre la tabla a mano: el programa envía una consulta a la base de datos.
La idea
INSERT INTO
INSERT INTO dice en qué tabla y en qué columnas, y VALUES da los valores en el mismo orden:
La columna id no está en la lista. Es una clave primaria del tipo INTEGER PRIMARY KEY, así que SQLite misma le da un número uno mayor que el más grande: 21. Una columna que no está en la lista recibe su valor por defecto (para stock en la tienda es 0), y si no hay, NULL.
Un campo puede contener varias sentencias. Se ejecutan una tras otra, y el SELECT del final muestra qué pasó.
Cada campo tiene su propia base de datos y la conserva entre ejecuciones. Ejecuta la consulta otra vez: la segunda vez la base de datos la rechaza, porque Vesela ya está dentro con ese correo. El botón «Base nueva» devuelve la base de datos a como estaba al principio.
Míralo
Sin la lista de columnas
La lista de columnas se puede omitir. Entonces los valores deben cubrir todas las columnas, en el orden que tienen en la tabla:
Deja una fuera, y la base de datos lo rechaza:
Aquí falta id. Sin lista, la base de datos no puede saber qué valor es para qué columna. Así que lista siempre las columnas. De esa forma ves qué va dónde, y la consulta no se rompe cuando la tabla recibe una columna nueva.
Pruébalo
Un producto nuevo
La tienda empieza a vender ayran. Añade el producto «Ayran» en la categoría 4 (Lácteos), a 1,30 €, con 30 en existencias, añadido hoy (2026-10-25).
Solución
INSERT INTO products (name, category_id, price, stock, added_at)
VALUES ('Ayran', 4, 1.3, 30, '2026-10-25');INSERT INTO products (name, category_id, price, stock, added_at) VALUES ('Ayran', 4, 1.3, 30, '2026-10-25'). Su número es 26, y la base de datos lo asigna sola.
La idea
RETURNING
Yavor Penev hace su primer pedido. El sitio web guarda el pedido y después tiene que guardar los productos que lleva. Para eso necesita el número del pedido nuevo, y ese lo reparte la base de datos.
RETURNING al final de un INSERT devuelve columnas de la fila que acaba de guardarse:
El pedido es el número 61. Sin RETURNING necesitarías una segunda consulta para saberlo. RETURNING acepta cualquier columna: RETURNING id, ordered_at o RETURNING *.
Más precisamente, para curiosos
RETURNING existe en SQLite (desde la versión 3.35) y en PostgreSQL. En SQL Server lo mismo se escribe con OUTPUT. MySQL no lo tiene: allí el número se lee con LAST_INSERT_ID() después de insertar. SQLite tiene una función parecida, last_insert_rowid().
La idea
Muchas filas a la vez
El pedido de Yavor lleva café y dos cartones de leche fresca. Varias filas entran con un solo INSERT: después de VALUES van varios paréntesis, separados por comas. En esta base de datos el pedido 61 ya existe:
Las filas también pueden venir de una consulta. Maria hace clic en «Pedir otra vez» en su último pedido (60). El pedido nuevo es el 61, y los productos vienen de un SELECT en lugar de VALUES:
Esto es INSERT … SELECT: lo que devuelve el SELECT se guarda. Las columnas del SELECT deben coincidir con la lista después de INSERT INTO. El precio se toma de products, no del pedido antiguo, porque puede haber cambiado desde entonces.
Míralo
La base de datos dice que no
Las tablas de la tienda tienen reglas. Rompe una, y la base de datos rechaza la fila y dice qué regla se rompió.
El correo de un cliente debe ser único (UNIQUE):
El nombre no puede faltar (NOT NULL):
El precio no puede ser negativo (CHECK):
Un pedido debe pertenecer a un cliente que exista. customer_id es una clave foránea hacia customers, y no hay cliente 99:
Cada vez la fila no se guarda y nada cambia en la base de datos. Eso es bueno: un error del programa no puede llenar la base de datos de pedidos que no pertenecen a nadie.
Estas reglas se escriben en la propia tabla cuando se crea. En el módulo siguiente las escribirás tú.
Pruébalo
Una reseña sin texto
Simona Yordanova (cliente 17) da hoy, 2026-10-25, 5 estrellas a la leche fresca (producto 5), sin escribir ningún texto. Guarda la reseña.
Solución
INSERT INTO reviews (product_id, customer_id, rating, created_at)
VALUES (5, 17, 5, '2026-10-25');INSERT INTO reviews (product_id, customer_id, rating, created_at) VALUES (5, 17, 5, '2026-10-25'). La columna body no está en la lista, así que se queda en NULL. Puede estar vacía, pero rating no: pruébalo sin ella.
Ejercicio
Dos tareas
1. La tienda amplía su sección «Hogar» (categoría 2). Añade dos subcategorías con una sola consulta: «Jardín» y «Baño».
Las dos categorías nuevas en «Hogar»:
Solución
INSERT INTO categories (name, parent_id)
VALUES ('Jardín', 2),
('Baño', 2);INSERT INTO categories (name, parent_id) VALUES ('Jardín', 2), ('Baño', 2). parent_id es 2 porque forman parte de «Hogar». Sus números son 9 y 10.
2. Ognyan Slavov, de Varna, se registra hoy con el correo ognyan.s@example.com. El sitio web quiere mostrarle su perfil enseguida, con el número que le dio la base de datos. Guárdalo y devuelve la fila nueva completa con la misma consulta.
El cliente nuevo, la fila completa:
Solución
INSERT INTO customers (name, email, city, joined_at)
VALUES ('Ognyan Slavov', 'ognyan.s@example.com', 'Varna', '2026-10-25')
RETURNING *;INSERT INTO customers (name, email, city, joined_at) VALUES ('Ognyan Slavov', 'ognyan.s@example.com', 'Varna', '2026-10-25') RETURNING *. Es el cliente 21.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: WHERE: filtrar filas · NULL: sin valor · Clave primaria y clave foránea · JOIN: dos tablas en una consulta
- Continúa en: UPDATE: cambiar valores · DELETE: borrar filas · Upsert: insertar o cambiar · La base de datos: de CREATE a DROP
- Ejercicios sobre el tema: Cambiar los datos