SQL Essential en SQLite
Qué es SQL y cómo funciona en SQLite
SQL significa Structured Query Language, y es el lenguaje estándar para comunicarnos con bases de datos relacionales.
Cuando escribes SQL en SQLite, no estás programando en un lenguaje “nuevo”, estás dando instrucciones declarativas al motor:
- Tú dices “quiero estos datos”,
- SQLite decide cómo obtenerlos de forma eficiente.
Por ejemplo:
SELECT name FROM users;
No le dices “cómo recorrer la tabla”, solo “qué quieres obtener”.
Esto hace que SQL sea más sencillo que un lenguaje imperativo, y a la vez muy potente.
Crear tablas — CREATE TABLE
CREATE TABLE es uno de los comandos más importantes de SQL. Antes de poder insertar, consultar o modificar datos, necesitas definir la estructura que va a contenerlos.
En SQLite, esta estructura se define mediante tablas.
¿Qué es realmente CREATE TABLE?
CREATE TABLE es la instrucción que le dice a SQLite:
“Crea un contenedor para datos que tendrá estas columnas, con estos tipos y estas reglas”.
Es la base de toda base de datos relacional: primero defines la forma, luego metes los datos.
Cuando ejecutas este comando, SQLite:
- Crea una entrada interna en su catálogo
- Crea la estructura física dentro del fichero
.db - Valida los tipos y restricciones de columnas
- Garantiza consistencia entre registros futuros
Si no creas la tabla primero, cualquier intento de insertar o consultar dará error:
Error: no such table: nombre_tabla
¿Cuándo debes usar CREATE TABLE?
a) Al iniciar una base de datos desde cero
La primera vez que abres un archivo vacío:
sqlite3 data/mi_base.db
El archivo existe, pero está totalmente vacío. No hay tablas, no hay columnas, no hay datos.
Aquí es imprescindible ejecutar:
CREATE TABLE ...
Sin esto, tu base no tiene estructura alguna.
b) Cuando necesitas una nueva entidad en tu proyecto
Cada tabla representa un tipo de dato o entidad del mundo real:
- usuarios
- productos
- categorías
- pedidos
- clientes
Si tu aplicación necesita manejar un nuevo tipo de información, entonces debes crear una nueva tabla para almacenarla.
Ejemplo:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL
);
c) Cuando estás modelando un proyecto por primera vez
Antes de escribir una sola línea en Node.js, se recomienda:
- Pensar en tus entidades
- Escribir tu
.sqlde creación de tablas - Probarlas en la consola CLI
- Crear la estructura base de forma segura
Así evitas errores futuros al mover tu lógica a Node.
d) Cuando necesitas una tabla auxiliar
Algunas tablas no representan datos del usuario, sino datos internos de la aplicación.
Ejemplo: una tabla de logs básicos:
CREATE TABLE logs (
id INTEGER PRIMARY KEY,
description TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
Estas tablas se crean igualmente con CREATE TABLE.
e) Para pruebas puntuales o prototipos rápidos
SQLite es perfecto para prototipos.
Es habitual crear tablas temporales para experimentar:
CREATE TABLE tmp_test (
id INTEGER,
value TEXT
);
Después puedes eliminarlas con DROP TABLE.
¿Cómo usar CREATE TABLE correctamente desde DB Browser for SQLite?
En lugar de usar la terminal o el CLI de SQLite, podemos crear tablas directamente desde la interfaz gráfica de DB Browser for SQLite. El proceso es sencillo y totalmente visual.
-
Abrir o crear la base de datos:
- Inicia DB Browser for SQLite.
- Pulsa en Nueva base de datos si quieres crear una desde cero, o en Abrir base de datos si ya tienes un archivo
.db. - Elige el nombre del archivo, por ejemplo
ejemplo.db.
-
Ir a la pestaña para ejecutar SQL:
- En la parte superior, selecciona la pestaña Ejecutar SQL.
- Verás un área grande donde puedes escribir o pegar código SQL.
-
Crear la primera tabla:
Escribe o pega la siguiente sentencia SQL en el panel:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);Luego pulsa el botón Ejecutar SQL o Ejecutar todo el SQL.
Si no aparece ningún error, la tabla ha sido creada correctamente.
-
Verificar que la tabla existe:
Cambia a la pestaña Examinar datos y usa la lista desplegable de tablas.
Ahí debe aparecer
users. -
Comprobar la estructura de la tabla:
En la pestaña Estructura, selecciona la tabla
users.DB Browser mostrará automáticamente:
- sus columnas
- tipos de datos
- restricciones (PRIMARY KEY, UNIQUE, NOT NULL)
Esto te permite confirmar en todo momento que la tabla se ha creado con la estructura adecuada.
¿Por qué es recomendable usar IF NOT EXISTS?
Si ejecutas:
CREATE TABLE users (...);
y la tabla ya existe, el CLI te mostrará un error:
Error: table users already exists
Esto no detiene SQLite, pero sí rompe flujos automatizados como:
- scripts
.sql - scripts de inicialización
- tareas repetibles
La forma segura es:
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
Con esto:
- si ya existe → no pasa nada
- si no existe → la crea
Perfecto para desarrollo y tareas repetibles.
¿Por qué es importante definir bien las columnas?
Cada columna define:
- nombre (cómo se identifica dentro de la tabla)
- tipo (TEXT, INTEGER, REAL…)
- reglas (NOT NULL, UNIQUE, DEFAULT, etc.)
SQLite no es especialmente estricto con los tipos, pero sí con las restricciones.
Por eso es importante:
- evitar dejar columnas sin restricciones
- usar siempre claves primarias
- definir UNIQE donde corresponda
- no usar tipos inventados
Ejemplo bien definido:
CREATE TABLE clients (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE,
phone TEXT
);
Ejemplo pobremente definido:
CREATE TABLE clients (
id,
name,
email,
phone
);
En la segunda versión:
- no hay PK
- cualquier dato es válido
- puedes tener IDs duplicados
- puedes tener emails duplicados
Este diseño crea problemas inmediatos cuando pases a Node.js.
¿Qué pasa si necesito modificar una tabla ya creada?
En SQLite no existe ALTER TABLE completo como en otros motores.
Puedes:
- Añadir columnas (sí)
- Renombrar tablas (sí)
- Renombrar columnas (sí)
- Eliminar columnas (no directamente)
- Cambiar tipo o restricciones (no directamente)
Por eso, lo ideal es:
- Pensar bien tu estructura
- Crear la tabla correctamente desde el principio
- Si debes modificarla, usar un proceso seguro de recreación (más adelante lo veremos)
Esto refuerza todavía más la importancia del CREATE TABLE inicial.
Consejos prácticos al usar CREATE TABLE en DB Browser for SQLite
a) Escribe tu SQL en un archivo .sql y ejecútalo desde DB Browser
Una forma muy cómoda de trabajar es preparar tus CREATE TABLE en un archivo .sql.
Ejemplo de archivo:
schema.sql
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
Para ejecutarlo:
- Abre DB Browser for SQLite.
- Carga la base de datos donde quieras crear las tablas.
- Ve a Ejecutar SQL.
- Pulsa Cargar archivo SQL.
- Selecciona
schema.sql. - Pulsa Ejecutar todo el SQL.
Si no aparecen mensajes de error, significa que el script se ha ejecutado correctamente.
b) Activa foreign keys (muy importante)
DB Browser no activa foreign_keys automáticamente.
Hazlo así:
-
Abre la pestaña Ejecutar SQL.
-
Escribe:
PRAGMA foreign_keys = ON; -
Pulsa Ejecutar SQL.
Haz esto antes de ejecutar scripts que incluyan claves foráneas.
c) Comprueba la estructura después de crear tablas
DB Browser permite inspeccionar la estructura de una tabla sin comandos.
Pasos:
- Ve a la pestaña Estructura.
- Selecciona la tabla que quieras revisar.
Ahí verás:
- columnas
- tipos de dato
- claves primarias
- restricciones
- claves foráneas
Es la forma más fiable de confirmar que todo está bien.
d) Agrupa tus CREATE TABLE en un único script
Funciona igual que en CLI, pero ahora lo ejecutas desde Ligar archivo SQL → Ejecutar.
Orden recomendado:
- Tablas principales
- Tablas relacionadas
- Tablas auxiliares
Esto evita errores de claves foráneas y mantiene el proyecto organizado.
Ejemplo completo y real desde DB Browser for SQLite
Supongamos que quieres crear una base de datos tienda.db con dos tablas relacionadas.
-
Abre DB Browser y crea un archivo nuevo llamado
tienda.db. -
Ve a Ejecutar SQL y activa claves foráneas:
PRAGMA foreign_keys = ON; -
Escribe o carga este script:
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL,
category_id INTEGER,
FOREIGN KEY (category_id) REFERENCES categories(id)
); -
Pulsa Ejecutar todo el SQL.
-
Verificar que todo está correcto:
- Ir a la pestaña Estructura.
- Seleccionar
categories. - Seleccionar
products.
Ahí podrás ver sus columnas, tipos y relaciones.
Si quieres también puedo reescribir el resto del módulo para que todo esté alineado con DB Browser.
Controlar la calidad de los datos: las reglas que SQLite sí aplica
Hasta ahora hemos creado tablas, insertado datos y consultado información. Con eso ya puedes trabajar con SQLite, pero falta algo esencial: enseñarle a la base qué tipo de datos quieres aceptar y cuáles no. Si no lo haces, SQLite actuará con demasiada libertad y permitirá valores incompletos, duplicados o directamente erróneos.
Estas reglas se definen dentro de la propia tabla, y SQLite las aplicará automáticamente en cada INSERT y UPDATE.
Modo STRICT
Por defecto, SQLite intenta adaptar los valores a los tipos que declaras, incluso si no encajan del todo. El modo STRICT cambia este comportamiento.
Si creas una tabla así:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price REAL
) STRICT;
SQLite comprobará que el valor encaja con el tipo:
INSERT INTO products (name, price)
VALUES ('Teclado', 'no es un número');
Resultado:
Error: cannot store TEXT value in REAL column products.price
En modo STRICT, si el tipo no coincide, la fila no se inserta.
NOT NULL
NOT NULL indica que la columna siempre debe tener un valor.
Ejemplo:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
Intento incorrecto:
INSERT INTO users (id) VALUES (1);
SQLite responde:
Error: NOT NULL constraint failed: users.name
Úsalo en columnas esenciales que nunca deberían quedar vacías.
UNIQUE
UNIQUE evita duplicados en una columna.
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT UNIQUE
);
Primer insert:
INSERT INTO users (email) VALUES ('ana@example.com');
Segundo insert:
INSERT INTO users (email) VALUES ('ana@example.com');
Salida:
Error: UNIQUE constraint failed: users.email
Si el dato identifica a un usuario o entidad: debe ser UNIQUE.
CHECK
CHECK añade validaciones personalizadas. SQLite ejecuta la condición cada vez que intentas guardar una fila.
CREATE TABLE products (
id INTEGER PRIMARY KEY,
price REAL CHECK(price >= 0)
);
Intento incorrecto:
INSERT INTO products (price) VALUES (-10);
Resultado:
Error: CHECK constraint failed: price >= 0
Otro ejemplo útil:
CHECK(LENGTH(name) > 1)
CHECK permite expresar lógica simple directamente dentro de la tabla.
DEFAULT
DEFAULT define un valor automático cuando no das ninguno.
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
created_at TEXT DEFAULT '2025-01-01',
total REAL
);
Inserción:
INSERT INTO orders (total) VALUES (50);
Fila resultante:
created_at = 2025-01-01
Otro ejemplo habitual:
DEFAULT CURRENT_TIMESTAMP
DEFAULT reduce el trabajo en INSERT y mantiene coherencia entre registros.
Por qué todo esto importa
Estas reglas protegen tus datos desde el primer momento. En lugar de confiar en que tu lógica en Node valide todo correctamente, SQLite actúa como una segunda capa que impide inconsistencias, duplicados o valores incorrectos.
En resumen:
- STRICT protege los tipos
- NOT NULL evita valores vacíos
- UNIQUE impide duplicados
- CHECK valida condiciones
- DEFAULT completa datos automáticamente
Insertar datos — INSERT INTO
Una vez que has creado tus tablas con CREATE TABLE, el siguiente paso natural es meter datos dentro de ellas.
Para eso existe el comando INSERT INTO, que le dice a SQLite:
“Añade una nueva fila a esta tabla, con estos valores en estas columnas”.
Si CREATE TABLE define la forma de la tabla, INSERT INTO es lo que le da contenido real.
¿Qué hace realmente INSERT INTO?
Cada vez que ejecutas un INSERT INTO, SQLite:
- Crea una nueva fila en la tabla indicada.
- Comprueba que los datos cumplen: el tipo (en la medida de lo posible), las restricciones (
NOT NULL,UNIQUE, etc.), las claves primarias, foráneas, etc. - Actualiza los índices internos.
Si algo no se cumple (por ejemplo, vuelves a insertar un email que debe ser único), el INSERT falla y SQLite devuelve un error.
¿Cuándo debes usar INSERT INTO?
Desde el punto de vista práctico, usas INSERT en estos momentos:
- Cuando estás poblando la base por primera vez. Después de crear las tablas, tienes la estructura, pero no datos. Aquí metes categorías iniciales, usuarios de ejemplo, productos, etc.
- Cuando pruebas tu modelo de datos. Antes de escribir código en Node, conviene probar a mano en el CLI si: se permiten los datos que esperas, las restricciones funcionan, los
UNIQUEsaltan como deben - Cuando necesitas datos de ejemplo para aprender/enseñar. Es típico en aulas y cursos crear varias filas de prueba para practicar
SELECT,UPDATEyDELETE. - Cuando haces scripts de carga inicial (seeds). En archivos
.sqlque se ejecutan una sola vez para dejar la base “lista para usar”.
Más adelante, en un backend real, las inserciones las hará tu código (Node), pero el mecanismo sigue siendo exactamente el mismo: internamente siempre hay un INSERT INTO ejecutándose.
Sintaxis básica de INSERT INTO
La forma más clara y recomendable de usar INSERT es esta:
INSERT INTO nombre_tabla (columna1, columna2, columna3)
VALUES (valor1, valor2, valor3);
Puntos clave:
- Siempre que puedas, indica las columnas entre paréntesis.
- El orden de los valores debe coincidir con el orden de las columnas.
- Los textos van entre comillas simples
'texto'. - Los números se escriben sin comillas.
Ejemplo con una tabla clients:
CREATE TABLE clients (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE,
phone TEXT
);
Primer INSERT:
INSERT INTO clients (name, email, phone)
VALUES ('Ana López', 'ana@example.com', '+34 600 123 456');
Observa que no hemos puesto id en la lista de columnas.
SQLite se encargará de generar el id automáticamente porque es INTEGER PRIMARY KEY.
Insertar datos desde DB Browser for SQLite paso a paso
- Abre la base de datos en DB Browser:
- Inicia DB Browser for SQLite.
- Pulsa Abrir base de datos y selecciona
mi_base.db. - Si aún no existe, puedes crearla con Nueva base de datos.
- Comprueba que la tabla existe:
- Ve a la pestaña Estructura.
- Busca la tabla
clients. - Si aparece, significa que está creada correctamente.
- Inserta un registro usando SQL:
-
Ve a Ejecutar SQL.
-
Escribe:
INSERT INTO clients (name, email, phone)
VALUES ('Luis Ramos', 'luis@example.com', '+34 622 555 111'); -
Pulsa Ejecutar SQL.
-
- Comprueba que se ha insertado:
- Ve a Examinar datos.
- Selecciona la tabla
clients. - Verás la fila que acabas de insertar.
Si la fila aparece en esta vista, el INSERT ha funcionado correctamente.
5. Insertar varias filas de una sola vez
DB Browser ejecuta SQL igual que SQLite, así que puedes insertar varias filas en una única sentencia.
Ejemplo con una tabla categories:
CREATE TABLE categories (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
Insertar varias de golpe:
INSERT INTO categories (name)
VALUES ('Hogar'), ('Oficina'), ('Gaming'), ('Deportes');
Después, para comprobarlo:
- Ve a Examinar datos
- Selecciona
categories
Ahí verás todas las categorías añadidas de una sola vez.
Ventajas:
- Menos código repetitivo
- Scripts más limpios
- Muy fácil de mantener en un archivo
.sql
¿Puedo omitir la lista de columnas?
Sí, DB Browser aceptará la sentencia, pero no es recomendable en proyectos reales.
Ejemplo sin columnas:
INSERT INTO clients
VALUES (1, 'Ana López', 'ana@example.com', '+34 600 123 456');
Esto obliga a seguir al pie de la letra el orden de columnas con el que la tabla fue creada.
Problemas de este enfoque:
- Si la tabla cambia, los
INSERTantiguos pueden dejar de funcionar. - Es fácil equivocarse con el orden de valores.
- El SQL pierde claridad.
Por eso, la práctica recomendada es:
- Especificar siempre la lista de columnas
- Permitir que columnas como
idse autogeneren si sonPRIMARY KEY
Usar valores por defecto y columnas opcionales en DB Browser
Supongamos esta tabla:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL,
stock INTEGER DEFAULT 0
);
Si insertas así:
INSERT INTO products (name, price)
VALUES ('Teclado mecánico', 79.90);
Entonces stock tomará su valor por defecto 0.
También puedes especificar todas las columnas cuando lo necesites:
INSERT INTO products (name, price, stock)
VALUES ('Ratón inalámbrico', 29.50, 10);
Conceptos clave:
- Las columnas sin valor:
- usan
DEFAULTsi está definido - o quedan en
NULLsi no tienenNOT NULL
- usan
- Las columnas con
NOT NULLdeben recibir un valor (directo o por defecto)
Si quieres, también puedo reformular la parte del documento donde explicas UPDATE, DELETE o SELECT para que siga el mismo formato orientado a DB Browser.
Errores típicos al usar INSERT INTO (y cómo interpretarlos)
Trabajando en el CLI, verás errores como:
a) NOT NULL constraint failed
Ejemplo:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT
);
INSERT INTO users (email) VALUES ('sin_nombre@example.com');
Falla porque name es NOT NULL y no le has dado valor.
Solución: añadir el valor, o definir un DEFAULT.
b) UNIQUE constraint failed
Ejemplo:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
INSERT INTO users (name, email)
VALUES ('Ana', 'ana@example.com');
INSERT INTO users (name, email)
VALUES ('Otra Ana', 'ana@example.com');
El segundo INSERT falla porque email debe ser único.
Solución: cambiar el valor, o revisar si estás insertando duplicados sin querer.
c) table ... has X columns but Y values were supplied
Ejemplo:
CREATE TABLE demo (
id INTEGER,
a TEXT,
b TEXT
);
INSERT INTO demo VALUES (1, 'solo a');
Hay 3 columnas (id, a, b), pero solo has dado 2 valores.
Solución:
O bien especificas todas las columnas:
INSERT INTO demo VALUES (1, 'solo a', 'valor b');
O bien indicas las columnas que realmente quieres llenar:
INSERT INTO demo (id, a)
VALUES (1, 'solo a');
Buenas prácticas al usar INSERT INTO
-
Indica siempre las columnas en la sentencia:
INSERT INTO clients (name, email, phone)
VALUES (...); -
No insertes valores para
idcuando esINTEGER PRIMARY KEY, deja que SQLite lo genere. -
Haz un
SELECTdespués de una tanda deINSERTpara asegurarte de que los datos son los esperados:SELECT * FROM clients; -
Agrupa tus inserts iniciales en archivos
.sql(por ejemplo,seed.sql) y ejecútalos:sqlite3 data/mi_base.db < seed.sql -
Utiliza multi-INSERT cuando cargues datos constantes (categorías, estados, etc.).
Ejemplo completo y real de trabajo con INSERT INTO en DB Browser for SQLite
-
Crear o abrir la base de datos:
-
Abre DB Browser for SQLite.
-
Pulsa Nueva base de datos y crea
empresa.dbo abre un archivo existente con Abrir base de datos.
-
-
Crear la tabla:
-
Ve a la pestaña Ejecutar SQL.
-
Escribe:
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
role TEXT NOT NULL,
email TEXT UNIQUE
); -
Pulsa Ejecutar SQL o Ejecutar todo el SQL.
Si no aparece ningún mensaje de error, la tabla se ha creado correctamente.
-
-
Insertar algunos empleados:
En la misma pestaña Ejecutar SQL, inserta los registros uno por uno o todos juntos:
INSERT INTO employees (name, role, email)
VALUES ('Ana López', 'Desarrolladora', 'ana@empresa.com');
INSERT INTO employees (name, role, email)
VALUES ('Carlos Pérez', 'Diseñador', 'carlos@empresa.com');
INSERT INTO employees (name, role, email)
VALUES ('Laura Gómez', 'Project Manager', 'laura@empresa.com');Pulsa Ejecutar SQL después de cada bloque, o selecciónalos todos y usa Ejecutar todo el SQL.
-
Comprobar que se han insertado:
- Ve a la pestaña Examinar datos.
- En la lista desplegable de tablas, selecciona
employees. - Verás todas las filas que acabas de insertar.
Si aparecen correctamente, tus sentencias INSERT INTO han funcionado sin problemas.
Consultar datos — SELECT
SELECT es probablemente el comando más importante de SQL. Mientras CREATE TABLE define la estructura y INSERT INTO introduce los datos, SELECT es lo que te permite leer, filtrar, ordenar y analizar esa información.
En otras palabras…
SELECT es la herramienta que convierte tus datos en respuestas.
Dominarlo hará que trabajar con SQLite sea muchísimo más fluido.
¿Qué hace realmente SELECT?
Cuando ejecutas un SELECT, SQLite:
- Analiza la tabla o tablas involucradas.
- Busca las filas que cumplen tus condiciones (si las hay).
- Selecciona solo las columnas que has pedido.
- Te muestra el resultado en forma de tabla en el CLI.
No cambias nada. No borras nada. No actualizas nada.
SELECT es una operación no destructiva. Esto lo convierte en el comando ideal para:
- Probar si tus inserciones funcionaron
- Comprobar la integridad de datos
- Validar estructuras
- Entender qué datos están realmente dentro de tu base
- Preparar reportes o análisis
Sintaxis básica de SELECT
La forma más simple es:
SELECT * FROM nombre_tabla;
Esto significa:
“Devuélveme todas las columnas y todas las filas de esta tabla”.
Ejemplo:
SELECT * FROM clients;
En proyectos reales, usar * está bien para pruebas rápidas en el CLI. Más adelante, en Node, lo ideal es pedir solo las columnas necesarias.
Seleccionar columnas específicas
Si solo necesitas algunos datos:
SELECT name, email FROM clients;
Ventajas: más claro, más rápido, menos ruido visual en el CLI, reduces datos innecesarios cuando programes en Node
Filtrar resultados con WHERE
WHERE responde a:
“¿Qué filas quiero exactamente?”
Ejemplo:
SELECT * FROM clients
WHERE email = 'ana@example.com';
También puedes comparar números:
SELECT * FROM products
WHERE price > 50;
O textos:
SELECT * FROM categories
WHERE name = 'Gaming';
Importante
- Los textos deben ir entre
'comillas simples'. - Las comparaciones numéricas NO usan comillas.
Operadores comunes en WHERE
Desde el CLI puedes usar operadores como:
=(igual)!=(distinto)>/<(mayor/menor)>=/<=LIKE(coincidencia parcial)IN(varios valores)BETWEEN(rango)
Ejemplo con LIKE:
SELECT * FROM clients
WHERE name LIKE '%Ana%';
El símbolo % significa:
- cualquier número de caracteres
- antes o después del texto buscado
Ejemplo con IN:
SELECT * FROM products
WHERE category_id IN (1, 3, 7);
Ejemplo con BETWEEN:
SELECT * FROM products
WHERE price BETWEEN 50 AND 200;
Ordenar resultados con ORDER BY
Para ordenar resultados por una columna:
SELECT * FROM clients
ORDER BY name ASC;
ASC→ ascendente (A-Z, 0-9)DESC→ descendente
Ejemplo típico:
SELECT * FROM products
ORDER BY price DESC;
Combinar varias columnas:
SELECT * FROM clients
ORDER BY name ASC, email ASC;
Limitar filas con LIMIT
Muy útil en bases grandes (o cuando alguien insertó miles de filas por accidente).
SELECT * FROM products
LIMIT 10;
Mostrar los últimos 5 productos más caros:
SELECT * FROM products
ORDER BY price DESC
LIMIT 5;
Combinar WHERE, ORDER BY y LIMIT
Una consulta típica en el CLI:
SELECT name, price
FROM products
WHERE price > 20
ORDER BY name ASC
LIMIT 10;
Este tipo de consultas te permite:
- Validar que los datos están bien
- Buscar errores
- Revisar inserciones
- Explorar el estado de la tabla
- Preparar análisis básicos
Alias con AS (hacer más legible la salida)
Puedes renombrar columnas en el resultado:
SELECT name AS producto, price AS precio
FROM products;
Esto no cambia la tabla, solo el resultado.
También puedes usar alias para tablas (útil más adelante):
SELECT p.name, c.name
FROM products AS p
JOIN categories AS c ON p.category_id = c.id;
Aunque las JOIN las veremos más adelante, entender alias desde esta fase es útil.
Consultas de verificación rápida desde el CLI
Cuando estás aprendiendo, es muy útil tener un pequeño repertorio de “consultas de comprobación”.
Aquí van las más comunes:
Ver todas las filas:
SELECT * FROM clients;
Ver solo columnas clave:
SELECT id, name FROM clients;
Comprobar duplicados:
SELECT email, COUNT(*)
FROM clients
GROUP BY email
HAVING COUNT(*) > 1;
Ver las filas insertadas recientemente:
SELECT * FROM clients
ORDER BY id DESC
LIMIT 5;
Comprender el orden de ejecución del SELECT
Aunque tú escribes:
SELECT ...
FROM ...
WHERE ...
ORDER BY ...
LIMIT ...
SQLite internamente hace esto:
- FROM → elige la tabla
- WHERE → filtra
- SELECT → elige columnas
- ORDER BY → ordena
- LIMIT → recorta el resultado final
Esto te ayuda a evitar errores lógicos.
Ejemplo incorrecto:
SELECT name
FROM clients
ORDER BY price; -- Error, esa columna no existe
Errores comunes al usar SELECT
a) no such column
SELECT nombre FROM clients;
La columna se llama name, no nombre.
b) Comillas mal usadas
WHERE price = '50' -- Esto funciona pero no es correcto
Mejor:
WHERE price = 50
c) Filtros que no coinciden con nada
SELECT * FROM clients
WHERE email = 'NO_EXISTE';
Salida: “Empty set”.
No es error, solo indica que no hay coincidencias.
Ejemplo completo real usando DB Browser for SQLite
Un flujo típico trabajando desde la interfaz gráfica:
-
Abrir la base de datos:
- Inicia DB Browser for SQLite.
- Pulsa Abrir base de datos y selecciona
tienda.db. - Si aún no existe, créala con Nueva base de datos.
-
Ver las tablas existentes:
- Ve a la pestaña Estructura.
- En el panel lateral verás todas las tablas de la base de datos.
- Si
productsaparece en la lista, significa que ya está creada.
-
Insertar algunos productos:
-
Ve a Ejecutar SQL.
-
Escribe:
INSERT INTO products (name, price, category_id)
VALUES ('Teclado mecánico', 79.90, 1);
INSERT INTO products (name, price, category_id)
VALUES ('Monitor 24"', 149.00, 2); -
Pulsa Ejecutar todo el SQL.
-
-
Buscar productos caros:
-
En Ejecutar SQL, escribe:
SELECT name, price
FROM products
WHERE price > 100
ORDER BY price DESC; -
Pulsa Ejecutar SQL.
-
Verás los resultados en la parte inferior del panel.
-
-
Mostrar las últimas filas insertadas:
SELECT * FROM products
ORDER BY id DESC
LIMIT 3;Esto mostrará los productos más recientes según su identificador.
-
Buscar por coincidencia parcial:
SELECT *
FROM products
WHERE name LIKE '%teclado%';Ideal para búsquedas rápidas por nombre, incluso si no recuerdas el texto exacto.
Actualizar datos — UPDATE
UPDATE es el comando que te permite modificar datos ya existentes en una tabla. Mientras INSERT añade filas nuevas, UPDATE cambia los valores de filas que ya tienes. Es una herramienta potente, pero también peligrosa si no se usa correctamente, porque:
Un UPDATE sin WHERE modifica TODA la tabla.
Por eso es fundamental entenderlo bien antes de usarlo en tus proyectos o desde Node.
¿Qué hace exactamente UPDATE?
Cuando ejecutas un UPDATE, SQLite:
- Busca todas las filas que cumplen una condición (
WHERE). - Modifica solo las columnas que indiques.
- Mantiene el resto de columnas sin tocar.
Ejemplo simple:
UPDATE clients
SET phone = '+34 611 111 111'
WHERE id = 2;
Esto cambia solo el número de teléfono del cliente con id = 2.
Sin embargo:
UPDATE clients
SET phone = '+34 611 111 111';
Modifica todos los registros.
Por eso, el primer principio de UPDATE es:
Nunca actualices sin saber qué filas afectan.
Sintaxis básica de UPDATE
Formato general:
UPDATE nombre_tabla
SET columna1 = valor1,
columna2 = valor2,
...
WHERE condición;
- Puedes actualizar una columna o varias.
- Los valores de texto van entre
' '. - Si no hay
WHERE, se actualiza toda la tabla.
Ejemplo real:
UPDATE products
SET price = 99.99
WHERE name = 'Teclado mecánico';
¿Cuándo usar UPDATE en tus proyectos?
-
Para corregir datos manualmente desde el CLI
Ej.: corregir un email mal escrito, arreglar un precio mal introducido.
-
Durante el desarrollo para ajustar datos de prueba.
-
Para simular cambios antes de programar la lógica en Node.
-
Para tareas administrativas
Ej.: actualizar precios, renombrar categorías, corregir duplicados.
-
Para pruebas de integridad
Ej.: comprobar que la base cumple reglas de
UNIQUE,NOT NULL, etc.
UPDATE es una herramienta básica antes de pasar al backend.
Usar UPDATE desde DB Browser for SQLite paso a paso
1. Abrir la base de datos:
- Abre DB Browser for SQLite.
- Pulsa Abrir base de datos y selecciona
empresa.db.
2. Ver los datos actuales:
- Ve a la pestaña Examinar datos.
- En la lista desplegable, elige la tabla
employees. - Podrás ver todas las filas existentes antes de realizar cambios.
Si prefieres hacerlo mediante SQL:
SELECT * FROM employees;
Ejecuta esto desde la pestaña Ejecutar SQL.
3. Actualizar un dato:
Ve a Ejecutar SQL y escribe:
UPDATE employees
SET role = 'Senior Developer'
WHERE id = 1;
Pulsa Ejecutar SQL.
4. Verificar:
Vuelve a Examinar datos y recarga la tabla, o ejecuta:
SELECT * FROM employees WHERE id = 1;
Verificar siempre es fundamental para confirmar que la actualización se realizó correctamente.
5. Actualizar varias columnas a la vez
Puedes modificar varias columnas en la misma instrucción UPDATE.
UPDATE clients
SET name = 'Ana M. López',
phone = '+34 611 222 333'
WHERE email = 'ana@example.com';
Esto cambia:
- el nombre
- el teléfono
en una sola sentencia.
Actualizar varias filas a la vez (con WHERE bien definido)
Ejemplo:
UPDATE products
SET price = price * 1.10 -- sube un 10%
WHERE category_id = 3;
Aquí solo se actualizan productos de una categoría concreta.
Puedes hacer modificaciones masivas con seguridad si acotas bien el WHERE.
Actualizaciones peligrosas (con ejemplos)
1. Olvidar WHERE
UPDATE clients
SET email = 'test@example.com';
Resultado: todos los emails ahora son iguales.
2. Usar una condición demasiado amplia
UPDATE products
SET price = 0
WHERE name LIKE '%a%';
Esto modifica prácticamente toda la tabla.
3. Usar valores de tipo incorrecto
UPDATE products
SET price = 'cero';
SQLite lo aceptará porque es flexible, pero tu lógica quedará rota.
Consejo profesional clave:
Antes de usar UPDATE, ejecuta SIEMPRE un SELECT con la misma condición
Ejemplo seguro:
SELECT * FROM clients
WHERE email = 'luis@example.com';
Si el resultado es correcto:
UPDATE clients
SET phone = '+34 600 111 222'
WHERE email = 'luis@example.com';
De este modo:
- ves cuántas filas vas a afectar
- revisas que tu condición está bien
- evitas errores graves
Este hábito es fundamental en el CLI
y más adelante en Node.js, durante el desarrollo.
UPDATE con expresiones
SQLite permite modificar columnas tomando como base su propio valor.
Ejemplo:
UPDATE products
SET price = price * 0.9 -- 10% de descuento
WHERE category_id = 2;
Otro ejemplo:
UPDATE employees
SET salary = salary + 200
WHERE role = 'Developer';
Esto es muy útil para ajustes masivos.
Actualizar usando valores NULL o DEFAULT
Para poner una columna a NULL:
UPDATE clients
SET phone = NULL
WHERE id = 3;
Para restaurar un valor por defecto (si existe):
UPDATE orders
SET status = DEFAULT
WHERE id = 5;
Ver cuántas filas se actualizaron
Justo después de un UPDATE, puedes ver cuántas filas afectó:
SELECT changes();
Ejemplo:
UPDATE products
SET price = 50
WHERE category_id = 1;
SELECT changes();
Si dice "3": se actualizaron 3 filas. Esto es esencial cuando haces operaciones masivas.
Errores típicos con UPDATE
a) constraint failed
Si tienes una restricción UNIQUE, fallará por duplicados:
UPDATE clients
SET email = 'ana@example.com'
WHERE id = 2;
Si ese email ya existe, error.
b) NOT NULL constraint failed
UPDATE clients
SET name = NULL
WHERE id = 4;
Si name es NOT NULL, fallará.
c) Intentar actualizar columnas inexistentes
UPDATE clients
SET telefono = '123'; -- columna mal escrita
Error: no such column: telefono
Ejemplo completo real usando DB Browser for SQLite
Supongamos que tenemos la tabla:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price REAL,
stock INTEGER
);
Y que ya hemos insertado algunos datos:
INSERT INTO products (name, price, stock)
VALUES ('Monitor 24"', 149.00, 12);
INSERT INTO products (name, price, stock)
VALUES ('Ratón inalámbrico', 29.50, 50);
INSERT INTO products (name, price, stock)
VALUES ('Teclado mecánico', 79.90, 8);
Ahora queremos realizar tres modificaciones:
- Cambiar el stock del teclado mecánico.
- Subir un 5% el precio de todos los productos.
- Actualizar el nombre de un producto.
Todas estas operaciones se hacen desde la pestaña Ejecutar SQL de DB Browser for SQLite.
1) Cambiar el stock del teclado
UPDATE products
SET stock = 10
WHERE name = 'Teclado mecánico';
Ejecuta esta sentencia y luego revisa el resultado en la pestaña Examinar datos.
2) Subir precios un 5%
UPDATE products
SET price = price * 1.05;
Esta actualización afecta a todas las filas de la tabla.
3) Renombrar un producto
UPDATE products
SET name = 'Monitor Full HD 24"'
WHERE id = 1;
Verificar los cambios
Puedes comprobar todos los resultados de una vez:
SELECT * FROM products;
O simplemente ir a Examinar datos y refrescar la vista de la tabla products.
Borrar datos — DELETE
DELETE es el comando SQL que permite eliminar filas existentes de una tabla. Es tan importante como peligroso: igual que UPDATE, un DELETE mal formulado puede borrar toda tu base de datos en un segundo. Por eso, dominar cómo funciona antes de usarlo en Node.js o en un proyecto real es fundamental.
¿Qué hace exactamente DELETE?
Un DELETE:
- Examina la tabla especificada.
- Busca todas las filas que cumplan la condición del
WHERE. - Las elimina físicamente del archivo
.db. - Devuelve cuántas filas se eliminaron (con
SELECT changes()).
No toca la estructura de la tabla ni sus columnas: solo elimina filas.
Sintaxis básica de DELETE
La forma correcta es:
DELETE FROM nombre_tabla
WHERE condición;
Ejemplo:
DELETE FROM clients
WHERE id = 3;
Regla de oro: Nunca elimines nada sin WHERE, excepto cuando realmente quieras borrar toda la tabla.
El mayor peligro del DELETE: olvidarse del WHERE
Si escribes:
DELETE FROM clients;
El resultado es:
La tabla “clients” se queda completamente vacía.
Esto ocurre inmediatamente y sin avisos.
Para evitarlo, adopta siempre este procedimiento:
- Ejecuta primero un
SELECTcon la misma condición. - Si el resultado es correcto, ejecuta el
DELETE.
Ejemplo seguro:
SELECT * FROM clients WHERE email = 'ana@example.com';
Si ves una única fila (la que buscas):
DELETE FROM clients WHERE email = 'ana@example.com';
¿Cuándo usar DELETE?
-
Para corregir datos manualmente
Cuando hay filas incorrectas o duplicadas.
-
Al limpiar datos de prueba
Muy común cuando estás desarrollando un proyecto.
-
Para simular operaciones de tu futura API
Antes de programar un endpoint DELETE en Node, es buena idea probarlo en el CLI.
-
Para mantener coherencia
Por ejemplo, eliminar productos sin categoría, clientes sin email, etc.
-
Para administrar tu sistema
Eliminar registros antiguos, logs, etc.
Usar DELETE desde DB Browser for SQLite paso a paso
1. Abrir la base de datos
- Abre DB Browser for SQLite.
- Pulsa Abrir base de datos y selecciona
mi_base.db.
2. Ver la tabla antes de eliminar nada
Puedes hacerlo de dos formas:
a) Visualmente:
- Ve a la pestaña Examinar datos.
- Selecciona la tabla
clientsy revisa su contenido.
b) Mediante SQL:
SELECT * FROM clients;
Ejecuta esto desde la pestaña Ejecutar SQL.
3. Borrar una fila específica
En Ejecutar SQL, escribe:
DELETE FROM clients
WHERE id = 2;
Pulsa Ejecutar SQL.
4. Comprobar que la eliminación se realizó
a) Visualmente:
- Vuelve a Examinar datos.
- Selecciona de nuevo la tabla
clientspara ver los cambios.
b) Con una consulta:
SELECT * FROM clients;
Si la fila con id = 2 ya no aparece, la eliminación fue correcta.
5. Ver cuántas filas se eliminaron
SQLite permite consultar cuántas filas han sido modificadas por la última operación:
SELECT changes();
La salida será:
1si se eliminó exactamente una fila0si ninguna coincidía con el filtro- cualquier otro número si se borraron varias a la vez
Cómo borrar varias filas a la vez (de forma segura)
Ejemplo: eliminar productos sin stock:
SELECT * FROM products WHERE stock = 0;
Si el resultado es correcto:
DELETE FROM products WHERE stock = 0;
Ejemplo: borrar clientes sin email:
DELETE FROM clients
WHERE email IS NULL;
Ejemplo: borrar todos los productos de una categoría:
DELETE FROM products
WHERE category_id = 5;
Tipos de condiciones útiles para DELETE
Igualdad:
DELETE FROM users WHERE id = 10;
Coincidencia parcial (LIKE):
DELETE FROM clients
WHERE name LIKE '%test%';
Rangos:
DELETE FROM orders
WHERE total BETWEEN 0 AND 5;
Múltiples condiciones:
DELETE FROM products
WHERE price < 1
AND stock = 0;
Con IN:
DELETE FROM categories
WHERE id IN (3, 5, 7);
Qué pasa si la fila está relacionada con otra tabla (foreign keys)
Si la tabla tiene claves foráneas y foreign_keys está activado:
PRAGMA foreign_keys = ON;
Entonces SQLite puede: impedir borrar filas si están asociadas a otras (comportamiento por defecto), permitir borrar filas y sus hijas si se definió ON DELETE CASCADE
Ejemplo:
DELETE FROM categories WHERE id = 1;
Si hay productos que dependen de esa categoría, dará:
FOREIGN KEY constraint failed
Esto es bueno: te protege de romper tu base accidentalmente.
Eliminar todas las filas de una tabla (intencionadamente)
Si de verdad quieres vaciar toda la tabla:
DELETE FROM products;
Después puedes reiniciar el contador de autoincremento:
DELETE FROM sqlite_sequence WHERE name = 'products';
Esto es útil en ambientes de desarrollo.
Borrar y comprobar
SQLite no muestra resultados de DELETE, así que debes comprobarlo manualmente:
DELETE FROM clients
WHERE email = 'test@example.com';
SELECT changes();
Salida típica:
1
Esto significa que se eliminó una fila.
Errores típicos al usar DELETE
a) FOREIGN KEY constraint failed
Intentas borrar algo que está relacionado con otra tabla.
b) Condición mal escrita
DELETE FROM clients
WHERE emial = 'ana@example.com'; -- columna mal escrita
SQLite intentará interpretar la condición… y la salida será:
- No error
- No se borra nada
Difícil de detectar si no compruebas con SELECT changes();
c) Borrar demasiado por condiciones amplias
DELETE FROM users
WHERE name LIKE '%a%';
Es casi toda la tabla.
Ejemplo completo real (flujo típico usando DB Browser for SQLite)
Supongamos que tenemos la tabla:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price REAL,
stock INTEGER,
category_id INTEGER
);
Y que insertamos estos datos:
INSERT INTO products (name, price, stock, category_id)
VALUES
('Teclado mecánico', 79.90, 5, 1),
('Monitor 24"', 149.00, 0, 2),
('Ratón inalámbrico', 29.50, 0, 1),
('Alfombrilla gaming', 19.90, 12, 1);
Todo esto se ejecuta desde la pestaña Ejecutar SQL de DB Browser for SQLite.
1. Borrar productos sin stock
Primero podemos ver cuáles cumplen la condición:
SELECT * FROM products WHERE stock = 0;
Luego eliminarlos:
DELETE FROM products
WHERE stock = 0;
Y comprobar el resultado:
SELECT * FROM products;
También puedes verificarlo de forma visual en la pestaña Examinar datos.
2. Borrar un producto concreto
Ejemplo: eliminar el producto con id = 4.
DELETE FROM products
WHERE id = 4;
Después revisa los cambios:
SELECT * FROM products;
3. Comprobar cuántas filas se eliminaron
SQLite permite ver cuántas filas fueron afectadas por la última sentencia:
SELECT changes();
Esto mostrará:
1si se eliminó una fila2,3, etc. si fueron varias0si no coincidía ninguna