- Aprender
- Informática
- Programación
- Fundamentos de SQL
- Crear y modificar tablas de base de datos
Crear y modificar tablas de base de datos: restricciones
CREATE TABLE con tipos de datos adecuados, protege los datos con NOT NULL, UNIQUE, CHECK, claves primarias (llaves primarias) y claves foráneas (claves externas), y añade, modifica y elimina filas con INSERT, UPDATE y DELETE. Practica cómo seleccionar exactamente las filas adecuadas, agrupa cambios relacionados en transacciones que puedas confirmar o revertir y modifica o elimina tablas con ALTER TABLE y DROP TABLE. Los ejemplos utilizan SQL estándar que funciona en SQLite y PostgreSQL, y señalan las diferencias de MySQL, SQL Server y Oracle cuando son relevantes.PrincipianteUnidad 6 de 6 del curso Curso de Fundamentos de SQL
Lo que aprenderás
- Escribe sentencias
CREATE TABLEque definan una tabla y sus columnas, y elige para cada columna un tipo de datos adecuado para los valores que almacenará.- Escribe una sentencia CREATE TABLEDefine una tabla nueva con columnas con nombre, comprueba su estructura y evita los errores de sintaxis más habituales entre principiantes.
- Elige un tipo de datos para cada columnaElige tipos enteros, decimales exactos, de coma flotante, de texto, de fecha y de verdadero/falso para los valores de una columna, y comprende cómo se diferencia el tipado flexible de SQLite del de bases de datos más estrictas.
- Escribe una sentencia CREATE TABLE
- Utiliza restricciones para que la propia base de datos rechace valores ausentes, duplicados, fuera de intervalo o sin correspondencia, y asigna a cada fila una clave fiable.
- Exige valores, establece valores predeterminados y limita los valores permitidos con NOT NULL, DEFAULT, UNIQUE y CHECKDeclara las reglas de columna y tabla que mantienen los valores presentes, distintos y dentro del intervalo permitido, y predice qué inserciones rechazará una regla.
- Identifica filas mediante claves primarias e identificadores generadosDeclara claves primarias de una columna y compuestas, deja que la base de datos numere las filas nuevas y comprende qué garantizan y qué no los identificadores generados en cada sistema de bases de datos.
- Vincula tablas mediante claves foráneasDeclara claves foráneas que mantengan válidas las referencias entre tablas, elige qué ocurre cuando se elimina una fila referenciada y activa su aplicación donde esté desactivada.
- Exige valores, establece valores predeterminados y limita los valores permitidos con NOT NULL, DEFAULT, UNIQUE y CHECK
- Añade filas nuevas con
INSERT, de una en una, varias a la vez o copiadas de una consulta, y gestiona las claves generadas y los duplicados.- Inserta filas con VALUESEscribe sentencias
INSERT ... VALUEScon una lista de columnas y texto, números, fechas yNULLescritos correctamente, e interpreta los errores que impiden una inserción. - Inserta datos desde consultas, obtén las nuevas claves y gestiona los duplicadosCopia filas con
INSERT ... SELECT, recupera los valores generados conRETURNINGy decide qué ocurre cuando una fila insertada entra en conflicto con una existente.
- Inserta filas con VALUES
- Modifica valores con
UPDATEy elimina filas conDELETE, y asegúrate de que cada sentencia afecte exactamente a las filas previstas.- Modifica valores con UPDATEEscribe sentencias
UPDATEque asignen valores a una o varias columnas, calculen valores nuevos a partir de los anteriores y respeten las restricciones de la tabla. - Elimina filas con DELETEElimina las filas elegidas con
DELETE, distingue entreDELETE,TRUNCATEyDROP TABLE, y decide cuándo conviene marcar una fila como eliminada en lugar de borrarla. - Selecciona exactamente las filas que quieres modificar o eliminarConstruye condiciones
WHEREpara cambios que seleccionen las filas previstas y ninguna otra, y comprueba el resultado antes de conservarlo.
- Modifica valores con UPDATE
- Utiliza transacciones para conservar o deshacer en su conjunto un grupo de cambios relacionados y recuperarte de forma ordenada cuando falle una sentencia.
- Confirma o revierte un grupo de cambiosInicia una transacción, conserva sus cambios con
COMMITo deshazlos conROLLBACK, y comprende la confirmación automática. - Gestiona errores, puntos de guardado y cambios de estructura en una transacciónResponde correctamente cuando falle una sentencia dentro de una transacción, deshaz parte de una transacción con un punto de guardado y comprende qué bases de datos pueden revertir
CREATE,ALTERyDROP.
- Confirma o revierte un grupo de cambios
- Modifica la estructura de las tablas existentes sin perder sus filas y elimina tablas de forma segura cuando ya no sean necesarias.
- Añade, renombra y elimina columnas con ALTER TABLEUtiliza
ALTER TABLEpara añadir, renombrar y eliminar columnas y para modificar tipos y restricciones, y sortea las limitaciones de SQLite. - Elimina tablas con DROP TABLEElimina tablas con
DROP TABLE, respeta las dependencias entre tablas y elige entre eliminar una tabla, vaciarla y eliminar filas.
- Añade, renombra y elimina columnas con ALTER TABLE
Guía de estudio de Crear y modificar tablas de base de datos
1Crea tablas con tipos de datos adecuados para sus columnas
Una tabla necesita una estructura clara antes de poder contener datos útiles. Empieza por los datos que registra una fila, asigna un nombre a cada uno y elige cómo los almacenará la base de datos. Crearás una tabla vacía, inspeccionarás lo que se ha creado realmente y distinguirás un número utilizado para calcular de un texto que solo parece numérico. SQLite y PostgreSQL comparten gran parte de la sintaxis, pero sus reglas de tipos pueden producir resultados muy distintos.
1.1 Escribe una sentencia CREATE TABLE
La definición de una tabla describe qué puede contener cada fila. No añade ninguna fila. En una tienda en línea, cada producto necesita campos separados para su identificador, nombre, precio y cantidad en existencias.
Construye la definición
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(8, 2) NOT NULL,
in_stock INTEGER DEFAULT 0
);
Lee de fuera hacia dentro. CREATE TABLE products da nombre a la tabla nueva. Los paréntesis contienen las definiciones de sus columnas. Cada línea indica un nombre de columna, un tipo y las reglas de esa columna. Las comas separan las definiciones; la última no lleva coma. El punto y coma termina la sentencia. Tras ejecutarse correctamente, SELECT * FROM products; devuelve cero filas.
Esta declaración de clave genera identificadores en SQLite. En PostgreSQL, utiliza id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY para generarlos. La declaración decimal también se comporta de forma distinta en estos sistemas; elegir un almacenamiento exacto forma parte de la elección del tipo.
Asigna una columna a cada dato
Una fila de cliente podría contener id, first_name, last_name, email y signup_date. Agrupar «Ana Ruiz, ana@example.com» en un campo dificulta buscar o comprobar el nombre y el correo por separado. Nombra los campos según lo que contienen. Los nombres cortos en minúsculas unidos por guiones bajos, como unit_price, son fáciles de reutilizar.
Evita las palabras clave como nombres: orders funciona, mientras que order sin comillas entra en conflicto con la palabra clave ORDER de SQL. Un nombre con espacios necesita comillas dobles, como en "order date", cada vez que lo utilices. PostgreSQL convierte los nombres sin comillas a minúsculas, por lo que Products y products sin comillas hacen referencia al mismo nombre.
Las comillas simples tienen otra función: encierran valores de texto como 'Desk lamp'. Las comillas dobles identifican nombres. PostgreSQL interpreta "Desk lamp" como un nombre de columna, no como el texto de un producto.
Comprueba lo que se ha creado
Una coma final antes de ) provoca un error de sintaxis. La falta de una coma también suele hacerlo, pero SQLite puede interpretar varias palabras como un único nombre de tipo. CREATE TABLE t (a INTEGER b TEXT); crea una columna llamada a, no dos columnas. Inspecciona la definición:
- Consola de SQLite:
.schema productsmuestra la sentencia de creación. - SQL de SQLite:
PRAGMA table_info(products);enumera columnas y tipos. - psql de PostgreSQL:
\d productsmuestra columnas, tipos y restricciones.
CREATE TABLE IF NOT EXISTS products (...) evita un error cuando el nombre ya existe. No compara ni actualiza la definición anterior. Una tabla a la que le falte una columna necesaria seguirá igual.
Crea una copia puntual
CREATE TABLE cheap_products AS
SELECT name, price FROM products WHERE price < 10;
Esto crea columnas y copia las filas de la consulta. Los cambios posteriores en los productos no actualizan la copia. En SQLite y PostgreSQL, la tabla nueva no hereda la clave primaria ni las reglas NOT NULL o CHECK del origen.
CREATE, ALTER y DROP pertenecen al lenguaje de definición de datos, o DDL: modifican la estructura. INSERT, UPDATE y DELETE pertenecen al lenguaje de manipulación de datos, o DML: modifican filas. SELECT lee datos; los libros difieren en si lo incluyen en DML o asignan a las consultas su propia familia.
Puntos clave
- Las definiciones de columna contienen un nombre, un tipo y reglas opcionales.
- Utiliza comas entre las definiciones, sin coma al final.
- Las comillas simples encierran texto; las dobles, identificadores.
- Inspecciona la estructura resultante, también después de una sentencia IF NOT EXISTS.
- CREATE TABLE AS copia los datos de la consulta sin copiar las restricciones del origen.
1.2 Elige un tipo de datos para cada columna
Elige un tipo según la función que deba cumplir el valor. Una cantidad debe permitir cálculos aritméticos. Un código postal de EE. UU. debe conservar sus caracteres, incluidos los ceros iniciales. Ambos pueden contener cifras, pero necesitan almacenamientos distintos.
Elige tipos numéricos y de texto
| Valores | Tipo útil | Motivo |
|---|---|---|
| Recuentos enteros | INTEGER | Los recuentos no tienen parte fraccionaria. |
| Importes monetarios exactos en PostgreSQL | NUMERIC(p, s) | La aritmética decimal conserva los importes exactos. |
| Importes monetarios exactos en SQLite | Céntimos en INTEGER | Los céntimos enteros evitan el almacenamiento en coma flotante. |
| Medidas | REAL o DOUBLE PRECISION | Los valores aproximados son adecuados para cantidades medidas. |
| Nombres y códigos | TEXT o VARCHAR(n) | Se conservan los caracteres y los ceros iniciales. |
En PostgreSQL, NUMERIC(8, 2) tiene ocho cifras en total, dos tras la coma decimal. Su mayor valor positivo es 999 999,99. Insertar 12,345 almacena 12,35; 1 234 567,00 provoca un desbordamiento porque necesita siete cifras antes de la coma. DECIMAL es otro nombre de esta familia de tipos.
SQLite acepta NUMERIC(8, 2), pero no exige esa precisión ni esa escala. Almacena 19,99 en coma flotante y conserva 12,345 sin redondear. Almacena 1999 céntimos enteros para un importe exacto de 19,99. La coma flotante aproxima fracciones binarias: SELECT 0.1 + 0.2 = 0.3; de SQLite devuelve 0. PostgreSQL trata esos literales decimales sin conversión como valores numéricos exactos; conviértelos a DOUBLE PRECISION para ver el resultado aproximado.
Los números de texto se ordenan por caracteres: '100', '25', '9' aparecen en ese orden. Las cantidades numéricas necesitan columnas numéricas. El código postal '02139' debe ser texto; el almacenamiento como entero pierde su cero inicial.
El VARCHAR(20) de PostgreSQL rechaza textos de más de 20 caracteres. Su CHAR(n) rellena el texto más corto con espacios hasta una longitud fija. TEXT no tiene un límite de caracteres declarado. SQLite trata tanto VARCHAR(n) como CHAR(n) como texto, sin exigir la longitud ni añadir relleno.
Almacena fechas y valores sí/no
PostgreSQL tiene DATE, TIME, TIMESTAMP y BOOLEAN. Rechaza un DATE imposible como '2026-02-30'. SQLite no tiene un tipo de almacenamiento específico para fechas. Utiliza texto ISO como '2026-03-15', cuyo orden de caracteres coincide con el de las fechas. El texto de estilo estadounidense ordena mal las fechas de años distintos: '12/01/2025' se ordena después de '03/15/2026'.
Una marca de tiempo añade una hora, como en '2026-03-15 14:30:00'. PostgreSQL utiliza TRUE y FALSE para los booleanos; SQLite almacena 1 y 0 y acepta esas palabras clave. MySQL trata BOOLEAN como un entero pequeño; SQL Server utiliza BIT.
Comprende qué exige el sistema
Las tablas normales de SQLite utilizan afinidad de tipo, una preferencia de almacenamiento. Una columna INTEGER convierte '5' en 5, pero acepta 'abc' como texto. PostgreSQL rechaza el texto que no puede convertirse en un entero. SQLite 3.37.0 y posteriores admiten tablas STRICT, cuyos tipos permitidos son INT, INTEGER, REAL, TEXT, BLOB y ANY.
Para los pedidos, elige un id entero, un correo de texto, una fecha DATE de PostgreSQL o de texto ISO de SQLite, NUMERIC(10, 2) de PostgreSQL o céntimos enteros de SQLite para el total, y un booleano o un indicador 0/1 para el pago. NULL significa ausente o desconocido; no es un tipo ni equivale a cero o a una cadena vacía. Una columna lo acepta salvo que una regla lo prohíba.
Puntos clave
- Elige los tipos según su uso: aritmética, texto, tiempo o sí/no.
- La precisión de NUMERIC cuenta todas las cifras; la escala cuenta los decimales.
- Utiliza NUMERIC de PostgreSQL o céntimos enteros de SQLite para importes monetarios exactos.
- El texto de fecha ISO se ordena por fecha cuando se escribe de manera uniforme.
- La afinidad de SQLite permite mezclar tipos de almacenamiento; STRICT refuerza las comprobaciones de tipo.
- NULL marca un valor ausente o desconocido.
2Protege los datos mediante restricciones
Una base de datos puede comprobar reglas en el momento en que cambian los datos, sea cual sea el programa que envíe el cambio. Las reglas de columna controlan valores ausentes, duplicados e intervalos; las claves identifican filas y mantienen válidos los vínculos entre tablas. Seguirás inserciones aceptadas y rechazadas, elegirás identificadores generados y predecirás qué ocurre con los pedidos cuando se elimina un cliente. Estas reglas trabajan juntas: comprobar el precio cumple una función distinta de exigir que el precio esté presente.
2.1 Exige valores, establece valores predeterminados y limita los valores permitidos con NOT NULL, DEFAULT, UNIQUE y CHECK
Una restricción hace que la base de datos rechace datos que incumplen una regla declarada. La comprobación se ejecuta al insertar o actualizar filas, independientemente de la aplicación que envíe la sentencia. Las distintas reglas protegen distintas partes de un registro de producto.
Combina reglas en una tabla
Esta definición de SQLite genera la clave y comprueba los demás campos. Para PostgreSQL, sustituye la línea de la clave por una clave primaria de identidad.
CREATE TABLE products (
id INTEGER PRIMARY KEY,
sku TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
price NUMERIC(8, 2) NOT NULL CHECK (price > 0),
in_stock INTEGER NOT NULL DEFAULT 0 CHECK (in_stock >= 0)
);
NOT NULL exige un valor. UNIQUE impide repetir un SKU. CHECK (price > 0) rechaza los precios iguales a cero o negativos. Las existencias tienen un valor predeterminado de 0 y deben mantenerse no negativas. La declaración numérica de SQLite no proporciona aritmética decimal exacta, así que utiliza céntimos enteros cuando la exactitud sea importante.
Distingue entre omitir y asignar NULL
Inserta una lámpara de escritorio con SKU 'LAMP-01', nombre 'Desk lamp' y precio 24,99, omitiendo las existencias de la lista de columnas. La inserción se realiza correctamente y recibe existencias 0. Proporcionar existencias NULL no solicita el valor predeterminado: incumple NOT NULL.
Una taza de café con precio -3,50 incumple la comprobación del precio. Un segundo producto con SKU 'LAMP-01' incumple UNIQUE, aunque su nombre y precio sean distintos. Un bolígrafo sin nombre incumple NOT NULL. Lee la regla o columna mencionada en el error y corrige los datos de entrada.
La cadena vacía es un valor real. name TEXT NOT NULL acepta '' en SQLite y PostgreSQL. Añade CHECK (name <> '') para rechazarla. Oracle trata la cadena vacía como NULL, por lo que allí la misma entrada queda sujeta a otra regla.
Comprueba combinaciones y valores ausentes
Una regla de columna va después de su tipo. Una regla de tabla es un elemento independiente dentro de la definición de la tabla y puede comparar columnas:
CHECK (end_date >= start_date),
UNIQUE (order_id, product_id)
La primera rechaza una fecha de fin anterior a la de inicio. La segunda rechaza un par repetido: un producto puede aparecer en pedidos distintos, pero no dos veces en el mismo pedido. Una tabla puede tener varias restricciones de unicidad.
Una comprobación rechaza una fila cuando su condición es falsa. Si el precio es NULL, price > 0 es desconocido, por lo que se supera la comprobación. Por eso el precio del producto también necesita NOT NULL. PostgreSQL, SQLite y MySQL normalmente permiten varios valores NULL con UNIQUE; SQL Server permite uno en una restricción de unicidad de una sola columna. PostgreSQL 15 y posteriores ofrecen UNIQUE NULLS NOT DISTINCT cuando los valores ausentes también deben entrar en conflicto. Las versiones de MySQL anteriores a 8.0.16 ignoraban las reglas CHECK.
Asigna un nombre útil a una regla con CONSTRAINT price_positive CHECK (price > 0). El nombre ayuda a identificarla en un error y a eliminarla después. Una restricción comprueba exactamente su expresión: CHECK (email LIKE '%@%') detecta que falta una arroba, pero no puede detectar un error de escritura en una dirección que cumple el patrón.
Puntos clave
- NOT NULL rechaza valores ausentes, pero no rechaza cadenas vacías en SQLite ni PostgreSQL.
- DEFAULT rellena las columnas omitidas; un NULL explícito no solicita ese valor.
- UNIQUE puede proteger una columna o una combinación de columnas.
- CHECK rechaza condiciones falsas; añade NOT NULL cuando también deban rechazarse las desconocidas.
- Los errores de restricción identifican datos que necesitan corregirse.
2.2 Identifica filas mediante claves primarias e identificadores generados
Una clave primaria identifica una fila de forma fiable. Puede ser una columna o una combinación, pero una tabla tiene como máximo una clave primaria. La clave debe ser única y estar presente, de modo que otras sentencias puedan identificar una fila sin depender de su descripción.
Elige un identificador estable
Una clave natural es un identificador existente del mundo real, como el ISBN de un libro. Una clave sustituta es un identificador artificial, a menudo un entero generado. El correo de un cliente puede cambiar; un identificador de cliente generado puede mantenerse igual mientras eso ocurre.
Una clave compuesta identifica una combinación:
PRIMARY KEY (order_id, product_id)
Un pedido puede contener varios productos y un producto puede aparecer en varios pedidos. El par identifica una línea de pedido. Ninguna de las columnas necesita ser única por sí sola.
PostgreSQL, MySQL y SQL Server exigen claves primarias sin valores ausentes. Las tablas normales de SQLite conservan una excepción histórica: una clave primaria distinta de INTEGER PRIMARY KEY puede contener NULL. Utiliza code TEXT PRIMARY KEY NOT NULL para una clave de texto. Las tablas STRICT de SQLite también cierran esta brecha.
Deja que la base de datos genere el número
| Base de datos | Declaración de clave primaria generada |
|---|---|
| SQLite | id INTEGER PRIMARY KEY |
| PostgreSQL | id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY |
| MySQL | id INT AUTO_INCREMENT PRIMARY KEY |
| SQL Server | id INT IDENTITY(1, 1) PRIMARY KEY |
Omite id de la lista de columnas de la inserción para solicitar un valor generado. Un simple INTEGER PRIMARY KEY de PostgreSQL no lo genera. El código antiguo de PostgreSQL suele utilizar SERIAL.
En SQLite, INTEGER PRIMARY KEY es un alias del número interno de fila. Empieza con los identificadores generados 1, 2 y 3, y después elimina 3. El siguiente identificador generado normal vuelve a ser 3, uno más que el máximo actual. Con INTEGER PRIMARY KEY AUTOINCREMENT, es 4: no se reutiliza un número que haya tenido una fila confirmada. Un número de una inserción revertida sí puede reutilizarse. Esta garantía más fuerte requiere trabajo adicional, así que elígela cuando sea importante no reutilizar números.
Lee los identificadores sin tratarlos como recuentos
Los huecos son normales. Las eliminaciones los dejan, y PostgreSQL no devuelve los números a la secuencia tras inserciones fallidas o revertidas. Utiliza COUNT(*) para contar filas y una marca de tiempo para el momento de un suceso. El mayor identificador no responde de forma fiable a ninguna de esas preguntas.
La forma GENERATED ALWAYS de PostgreSQL normalmente rechaza un identificador explícito como 50. GENERATED BY DEFAULT y SERIAL aceptan valores explícitos, pero proporcionar 50 no hace avanzar el generador más allá de 50. Un valor generado posteriormente puede entrar en conflicto con él.
Para utilizar la clave de una fila nueva en una fila relacionada, recupera la clave:
INSERT INTO customers (first_name, last_name, email)
VALUES ('Dev', 'Patel', 'dev@example.com')
RETURNING id;
RETURNING funciona en PostgreSQL y SQLite 3.35.0 y posteriores. SQLite también ofrece last_insert_rowid(), MySQL ofrece LAST_INSERT_ID() y SQL Server utiliza OUTPUT. Lee el resultado de la inserción en lugar de adivinar el siguiente identificador.
Puntos clave
- Una clave primaria identifica una fila; una clave compuesta identifica una combinación.
- Las claves generadas utilizan declaraciones distintas en las distintas bases de datos.
- AUTOINCREMENT de SQLite impide reutilizar identificadores confirmados, con un coste adicional.
- Los huecos entre identificadores son normales; utiliza COUNT(*) para contar filas.
- RETURNING obtiene la clave realmente generada.
2.3 Vincula tablas mediante claves foráneas
El customer_id de un pedido debe apuntar a un cliente que exista. Una clave foránea hace que la base de datos compruebe ese vínculo. La tabla que contiene la referencia es la hija; la tabla a la que apunta es la padre.
Declara y aplica el vínculo
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id)
);
Aquí customers debe existir primero y su id debe ser una clave primaria o única. Haz coincidir los tipos de ambos lados. La forma de tabla, FOREIGN KEY (customer_id) REFERENCES customers(id), declara el mismo vínculo por separado de la columna.
Con la aplicación de las restricciones activada, un pedido para el cliente 99 falla si no existe el cliente 99. Actualizar un pedido para asignarlo a ese cliente inexistente también falla. Una clave foránea que admita nulos puede contener NULL, que significa que no hay una fila vinculada; NOT NULL hace obligatorio el vínculo.
En SQLite, ejecuta PRAGMA foreign_keys = ON; en cada conexión nueva antes de iniciar una transacción. Un cambio de configuración dentro de una transacción no tiene efecto. PostgreSQL y SQL Server aplican las restricciones de clave foránea normalmente, al igual que el motor predeterminado de MySQL, InnoDB.
Predice la eliminación de una fila padre
Utiliza los clientes 1, Ana, y 2, Ben. Los pedidos 101 y 102 pertenecen a Ana; 103 pertenece a Ben. Considera la eliminación del cliente 1 con distintas declaraciones:
| Acción ON DELETE | Resultado |
|---|---|
NO ACTION o RESTRICT | La eliminación falla mientras 101 y 102 hagan referencia a Ana. |
CASCADE | Se eliminan Ana, 101 y 102; se conservan Ben y 103. |
SET NULL | Se elimina a Ana; se conservan todos los pedidos, con 101 y 102 desvinculados. |
SET DEFAULT | Los valores que hacen referencia toman su valor predeterminado declarado. |
SET NULL necesita una columna que admita nulos. SET DEFAULT sigue teniendo que cumplir la clave foránea: un valor predeterminado no ausente debe identificar una fila padre existente. Un valor predeterminado NULL funciona cuando se permiten vínculos ausentes.
Elige según el significado de los datos. Las líneas de pedido suelen pertenecer por completo a su pedido, por lo que la cascada puede ser adecuada. Los pedidos que deben conservarse requieren una acción de bloqueo cuando alguien intenta eliminar a su cliente. Un vínculo opcional con un proveedor puede establecerse en NULL. Aplicar cascadas en todas partes permite que una eliminación borre más registros de lo que sugiere el nombre de su tabla.
Trabaja en orden de dependencias
Crea las tablas padre antes que las hijas e inserta las filas padre antes que las filas que hacen referencia a ellas. Al eliminar datos o tablas relacionados, trabaja de hijas a padres. Una acción ON UPDATE ofrece las mismas opciones cuando cambia la clave de la fila padre; ON UPDATE CASCADE copia la clave nueva a las hijas.
RESTRICT comprueba de inmediato. NO ACTION, la opción predeterminada, puede esperar hasta el final de la sentencia o, con una restricción diferible, hasta el final de la transacción. Ambas bloquean una eliminación normal que dejaría referencias sin correspondencia. Mantén estables los identificadores generados para que cambiar los datos de un cliente no obligue a cambiar todas las referencias a ese cliente.
Puntos clave
- Una clave foránea vincula valores de la tabla hija con una clave primaria o única existente de la tabla padre.
- NULL permite un vínculo opcional salvo que NOT NULL lo prohíba.
- CASCADE elimina las filas hijas; SET NULL las conserva sin su vínculo.
- Activa las claves foráneas de SQLite antes de BEGIN en cada conexión.
- Crea e inserta primero las tablas y filas padre; elimina primero las filas y tablas hijas.
- Elige las acciones según los registros que deban conservarse.
3Añade filas con INSERT
Añadir filas significa asignar cada valor a la columna correcta y dejar que la base de datos compruebe el resultado. Se puede introducir un producto directamente, añadir varios clientes juntos y copiar pedidos antiguos desde una consulta. También recuperarás una clave generada y elegirás cómo gestionar un SKU existente. La misma entrada puede representar unas existencias de sustitución o una entrega adicional, por lo que una inserción o actualización debe expresar con precisión el cambio previsto.
3.1 Inserta filas con VALUES
INSERT añade filas a una tabla existente. Su lista de columnas establece la correspondencia entre los valores que proporcionas y los campos que los reciben. Escribe esa correspondencia de forma explícita para que un cambio posterior en la tabla no altere sin avisar el significado de tus datos de entrada.
Asigna los valores por posición
INSERT INTO products (sku, name, price, in_stock)
VALUES ('LAMP-01', 'Desk lamp', 24.99, 12);
Lee los pares en orden: SKU recibe 'LAMP-01', el nombre recibe 'Desk lamp', el precio recibe 24,99 y las existencias reciben 12. Debe haber cuatro valores para estas cuatro columnas. Una discrepancia, como dos valores para tres columnas, provoca un error.
Sin la lista, los valores siguen el orden de columnas declarado en la tabla. SQLite exige proporcionar todas las columnas; PostgreSQL permite menos y asigna valores predeterminados a las columnas finales. Una lista explícita evita depender de cualquiera de estos comportamientos. También te permite colocar las columnas en un orden claro para los datos de entrada.
Un par intercambiado puede ser peor que un error de sintaxis. Proporcionar 9,99 como nombre y 'Desk lamp' como precio hace que PostgreSQL rechace el precio no numérico. La afinidad normal de SQLite puede almacenar el texto del nombre «9.99» y el texto del precio «Desk lamp» sin dar error. Vuelve a leer la fila insertada con SELECT para comprobar la correspondencia.
Escribe correctamente los valores literales
| Clase | Ejemplo SQL |
|---|---|
| Texto | 'Desk lamp' |
| Texto que contiene un apóstrofo | 'O''Brien' |
| Número | 1250.50 |
| Fecha ISO | '2026-03-15' |
| Valor ausente | NULL |
El apóstrofo duplicado almacena un solo apóstrofo. Los números no llevan símbolos monetarios ni separadores de millares; una coma separa valores, por lo que una coma dentro de un importe sin comillas cambia el número de valores. 'NULL' es el texto de cuatro letras «NULL», no un valor ausente.
Deja que los campos omitidos se rellenen solos
Una columna omitida recibe su valor predeterminado, o NULL si no tiene ninguno. Una clave generada recibe un valor generado. Este último comportamiento depende de la declaración: INTEGER PRIMARY KEY de SQLite genera identificadores; PostgreSQL requiere una declaración de identidad para este fin. Una clave primaria entera simple de PostgreSQL omitida de una inserción provoca un error porque su valor sería NULL.
PostgreSQL, MySQL y SQL Server permiten DEFAULT como marcador de valor. SQLite no lo acepta dentro de una lista VALUES; omite esa columna en su lugar. Un NULL explícito nunca solicita el valor predeterminado.
Añade varias filas juntas
INSERT INTO customers (first_name, last_name, email) VALUES
('Ana', 'Ruiz', 'ana@example.com'),
('Ben', 'Okafor', 'ben@example.com'),
('Chloe', 'Nguyen', 'chloe@example.com');
En una tabla vacía cuya clave generada empieza en 1, reciben los identificadores 1, 2 y 3. Con la gestión normal de restricciones, la sentencia de varias filas se ejecuta correctamente en su conjunto o falla en su conjunto. Si una fila infringe una regla, no se inserta ninguna de las filas de esta sentencia.
Un error UNIQUE señala una clave o valor duplicado; NOT NULL señala datos ausentes; CHECK señala una condición incumplida; y un error de clave foránea señala un vínculo no válido. Corrige el valor o la correspondencia prevista antes de volver a intentarlo.
Puntos clave
- Enumera las columnas y asigna cada valor a ellas por posición.
- Los campos omitidos reciben valores predeterminados o NULL; los identificadores generados requieren un generador.
- Utiliza comillas simples para el texto y duplica los apóstrofos incluidos en él.
- NULL y el texto NULL son distintos.
- Una inserción normal de varias filas falla en su conjunto si una fila infringe una restricción.
3.2 Inserta datos desde consultas, obtén las nuevas claves y gestiona los duplicados
No es necesario escribir las filas de una en una. Una consulta puede proporcionar las filas de una inserción, y una regla de conflicto puede indicar qué debe ocurrir cuando un valor único ya existe. Ambas funciones dependen de seleccionar con precisión los datos previstos.
Copia el resultado de una consulta
INSERT INTO archived_orders (id, customer_id, order_date, total)
SELECT id, customer_id, order_date, total
FROM orders
WHERE order_date < '2026-01-01';
No hay cláusula VALUES: la consulta proporciona los valores. Haz corresponder sus columnas seleccionadas con la lista de destino por posición. La tabla de destino debe existir y sus reglas siguen aplicándose.
Revisa primero el SELECT por separado. Los pedidos 201, 202 y 204 tienen las fechas 2025-11-03, 2025-12-19 y 2025-10-30 y los totales 45,00, 120,50 y 60,00. Los pedidos 203 y 205 tienen fechas de 2026. La consulta devuelve tres filas que suman 225,50 y la inserción copia esas tres. También puede copiar cero filas cuando el filtro no encuentra nada.
Una segunda ejecución intenta copiarlas de nuevo. Una clave primaria en el destino hace que eso falle en lugar de almacenar duplicados sin avisar. INSERT ... SELECT es una operación de copia; no elimina las filas de origen ni mantiene sincronizadas las dos tablas.
Las importaciones de archivos suelen pasar primero por una tabla de preparación. La consola de SQLite utiliza .import --csv file.csv staging; psql utiliza \copy. En una consulta posterior, TRIM(email) elimina los espacios de los extremos y NULLIF(TRIM(email), '') convierte un correo vacío o compuesto solo por espacios en NULL. Las restricciones de destino comprueban entonces las filas limpias.
Lee el resultado de una escritura
INSERT INTO customers (first_name, last_name, email)
VALUES ('Dev', 'Patel', 'dev@example.com')
RETURNING id;
El resultado proporciona el identificador de cliente generado para utilizarlo en una fila relacionada. PostgreSQL y SQLite 3.35.0 y posteriores admiten RETURNING en inserciones, actualizaciones y eliminaciones. MySQL utiliza LAST_INSERT_ID() para un identificador generado; SQL Server utiliza OUTPUT.
Decide cómo gestionar los duplicados
Con stock (sku TEXT PRIMARY KEY, qty INTEGER NOT NULL), supón que 'LAMP-01' tiene una cantidad de 12. Una inserción simple que propone el mismo SKU y una cantidad de 20 falla. En SQLite y PostgreSQL:
INSERT INTO stock (sku, qty) VALUES ('LAMP-01', 20)
ON CONFLICT (sku) DO UPDATE
SET qty = stock.qty + excluded.qty;
stock.qty es el 12 existente. excluded.qty es el 20 propuesto. Esta forma almacena 32, lo que corresponde a una entrega adicional. SET qty = excluded.qty almacena 20, lo que corresponde a un recuento de sustitución. DO NOTHING conserva 12 y omite la fila en conflicto. Cada variante parte de la misma cantidad original de 12.
Una inserción o actualización combina insertar una fila nueva con actualizar cuando hay un conflicto. El destino del conflicto debe tener una protección de unicidad adecuada. La familia equivalente de MySQL es ON DUPLICATE KEY UPDATE. Un INSERT simple no corrige un cliente existente: crea otra fila o provoca un error de unicidad. Utiliza UPDATE para una fila que sabes que existe y una inserción o actualización cuando la fila podría existir ya.
Puntos clave
- INSERT ... SELECT copia los resultados de la consulta en una tabla existente.
- Volver a ejecutar una copia requiere una política de duplicados deliberada.
- RETURNING devuelve valores de las filas realmente escritas.
- excluded identifica la fila propuesta en una inserción o actualización.
- Sustituye las existencias con excluded.qty; añade una entrega con stock.qty + excluded.qty.
- DO NOTHING omite un conflicto de unicidad sin actualizar la fila existente.
4Modifica y elimina filas con UPDATE y DELETE
Una sentencia válida que modifica datos puede afectar a las filas equivocadas. Actualizar un precio, eliminar un pedido y seleccionar los registros que se van a modificar son decisiones distintas. Calcularás valores nuevos a partir de los almacenados, distinguirás entre vaciar un campo y eliminar una fila, y construirás condiciones con fechas, valores ausentes y alternativas agrupadas. Una vista previa y la comprobación del resultado permiten ver el efecto antes de que una transacción haga permanente el cambio.
4.1 Modifica valores con UPDATE
UPDATE modifica valores de filas que ya existen. Indica una tabla, asigna valores nuevos con SET y después elige las filas de destino con WHERE. Las restricciones de la tabla comprueban los valores resultantes.
Asigna valores a uno o varios campos
UPDATE products
SET price = 22.50, in_stock = 30
WHERE id = 3;
El producto con clave 3 recibe ambos valores; las demás filas conservan los suyos. Las asignaciones utilizan comas. Escribir SET price = 22.50 AND in_stock = 30 no significa hacer dos asignaciones. PostgreSQL lo rechaza; SQLite trata el lado derecho como una expresión booleana y puede almacenar 0 o 1 en el precio.
Omitir WHERE es SQL válido y aplica el cambio a todas las filas. UPDATE products SET price = 0; establece el precio de todos los productos en cero si las reglas de la tabla lo permiten. Una vista previa con la condición prevista muestra si el destino es una fila, varias o ninguna.
Calcula a partir del valor almacenado
UPDATE products
SET price = price * 1.10;
Un precio de 20,00 pasa a ser 22,00 tras un aumento del 10 %. Un precio de 19,99 da un resultado sin redondear de 21,989. PostgreSQL almacena 21,99 en una columna NUMERIC(8, 2). SQLite no exige la escala, por lo que SET price = ROUND(price * 1.10, 2) solicita dos decimales. Para almacenar dinero con exactitud en SQLite, conserva céntimos enteros y haz explícita la decisión de redondeo de los céntimos.
La expresión debe incluir el valor anterior cuando el cambio es relativo. SET in_stock = in_stock - 1 resta una unidad; SET in_stock = 1 sustituye el recuento por uno.
En SQLite y PostgreSQL, todas las expresiones del lado derecho leen la fila anterior a la actualización. UPDATE t SET a = b, b = a; intercambia los valores de una fila de 1 y 2 a 2 y 1. La actualización de una sola tabla de MySQL evalúa las asignaciones de izquierda a derecha, por lo que la misma forma deja ambos en 2. No traslades esta suposición de un sistema a otro.
Ten presentes las reglas y los valores ausentes
Utiliza SET phone = NULL para vaciar un campo de teléfono. Para encontrar valores de teléfono ausentes, utiliza WHERE phone IS NULL. La igualdad con NULL no los encuentra.
Considera los precios 12,00, 3,00 y 8,50 protegidos por CHECK (price > 0). Restar 5 a todos los precios haría que el segundo fuera -2,00. Con la gestión normal de restricciones, ese fallo deshace toda la sentencia, por lo que incluso los precios que serían válidos se mantienen sin cambios.
Una actualización de clave primaria también debe cumplir las claves foráneas relacionadas. Un cambio de clave bloqueado falla mientras las filas hijas apunten a la clave anterior; ON UPDATE CASCADE les transmite el nuevo valor. Mantener estables los identificadores generados evita este trabajo adicional cuando cambian los datos descriptivos.
Interpreta el número de filas afectadas
psql informa de un resultado como UPDATE 3; changes() de SQLite informa del recuento de la última sentencia de cambio. Ambos incluyen las filas seleccionadas y actualizadas aunque el valor asignado sea igual al anterior. Un recuento de tres no garantiza tres valores visiblemente distintos. Compara el recuento con la vista previa e inspecciona después los campos relevantes, o utiliza RETURNING para ver directamente las filas afectadas.
Puntos clave
- SET asigna valores; WHERE elige filas.
- Separa las asignaciones con comas, no con AND.
- Utiliza el valor anterior de la columna en un cálculo relativo.
- Un fallo normal de restricción deshace toda la sentencia UPDATE.
- Los recuentos de filas afectadas pueden incluir filas cuyos valores siguieron siendo iguales.
4.2 Elimina filas con DELETE
DELETE elimina filas completas. Deja la tabla preparada para volver a contener filas. Para vaciar un campo se utiliza UPDATE ... SET column = NULL; DELETE email FROM customers no es SQL válido.
Sigue una eliminación filtrada
La tienda tiene estos pedidos:
| ID | Estado | Fecha del pedido |
|---|---|---|
| 201 | cancelado | 2025-11-03 |
| 202 | enviado | 2025-12-19 |
| 203 | cancelado | 2026-01-08 |
| 204 | cancelado | 2025-10-30 |
| 205 | vencido | 2026-02-14 |
DELETE FROM orders
WHERE status = 'cancelled'
AND order_date < '2026-01-01';
El pedido 201 cumple ambas pruebas, al igual que 204. El pedido 203 está cancelado, pero es demasiado reciente; 202 es suficientemente antiguo, pero está enviado. La sentencia elimina dos filas y conserva 202, 203 y 205. DELETE FROM orders; sin la condición eliminaría los cinco.
Utiliza datos relacionados para elegir filas
DELETE FROM order_items
WHERE order_id IN (
SELECT id FROM orders WHERE status = 'cancelled'
);
La consulta interna produce los identificadores de los pedidos cancelados. IN comprueba el order_id de cada línea frente a esa lista. Ejecuta la consulta interna por separado para inspeccionar las claves y después revisa las filas de las líneas con la misma condición.
Las claves foráneas también afectan a la eliminación. Una fila padre con filas hijas que la referencian puede estar protegida por NO ACTION o RESTRICT; una cascada elimina las filas hijas; SET NULL las conserva, pero borra el vínculo. Comprueba esas acciones al valorar el efecto de eliminar una fila padre, porque la tabla nombrada directamente puede no ser la única que cambie.
Elige qué debe conservarse
| Sentencia | Filas eliminadas | Qué se conserva |
|---|---|---|
DELETE ... WHERE ... | Filas que cumplen la condición | La tabla y las demás filas |
DELETE FROM orders; | Todas las filas | La tabla vacía |
TRUNCATE TABLE orders; | Todas las filas, sin WHERE | La tabla vacía |
DROP TABLE orders; | Todas las filas junto con la tabla | No queda la tabla orders |
PostgreSQL, MySQL, SQL Server y Oracle admiten TRUNCATE; SQLite no. Sus reglas de transacciones y dependencias varían según la base de datos. Una sentencia que parece una operación de vaciado rápido también debe ajustarse a esas reglas.
Conserva el historial con una eliminación lógica
UPDATE customers
SET deleted_at = '2026-03-15'
WHERE id = 7;
Una eliminación lógica marca la fila sin borrarla. Puede conservar el historial y permitir la restauración borrando la marca. Las consultas de clientes activos deben incluir WHERE deleted_at IS NULL; de lo contrario, los clientes marcados siguen apareciendo. Marcar los datos no los borra.
Una eliminación confirmada no puede deshacerse con un ROLLBACK posterior. La restauración necesita una copia guardada o una copia de seguridad. Dentro de una transacción abierta, una reversión aún puede restaurar las filas eliminadas. Comprueba los identificadores seleccionados y el recuento de filas afectadas antes de hacer permanente el resultado.
Puntos clave
- DELETE elimina filas; UPDATE puede vaciar un solo campo.
- Omitir WHERE vacía la tabla y conserva su estructura.
- IN puede seleccionar filas utilizando claves de otra tabla.
- Las acciones de clave foránea pueden ampliar o bloquear una eliminación.
- Una eliminación lógica requiere filtros de filas activas y no borra los datos almacenados.
- ROLLBACK restaura una eliminación solo mientras su transacción siga sin confirmar.
4.3 Selecciona exactamente las filas que quieres modificar o eliminar
Elegir las filas suele ser la parte más difícil de un cambio. El mismo filtro que resulta inofensivo en una consulta puede eliminar o actualizar demasiado al reutilizarlo en una escritura. Convierte la regla prevista en una condición y después inspecciona qué filas selecciona realmente.
Revisa la condición exacta
SELECT id, status, order_date FROM orders
WHERE status = 'cancelled'
AND order_date < '2026-01-01';
Esta vista previa devuelve los pedidos 201 y 204 en el ejemplo de la tienda con cinco pedidos. Reutiliza exactamente esa condición en la eliminación. Reescribirla al cambiar la orden crea una selección nueva sin comprobar.
Para una fila concreta, utiliza su clave primaria: WHERE id = 42 selecciona como máximo una fila. Un nombre descriptivo como 'Desk lamp' puede ser compartido por varios productos.
Agrupa las alternativas explícitamente
AND tiene mayor precedencia que OR. Compara:
WHERE status = 'cancelled'
OR status = 'expired' AND order_date < '2026-01-01'
con:
WHERE (status = 'cancelled' OR status = 'expired')
AND order_date < '2026-01-01'
La primera acepta todos los pedidos cancelados, con independencia de la fecha, más los pedidos vencidos anteriores a 2026. Selecciona 201, 203 y 204. La segunda aplica la prueba de fecha a ambos estados y selecciona 201 y 204. El pedido 203 muestra la diferencia porque está cancelado en 2026.
Incluye los valores ausentes de forma deliberada
WHERE customer_id = NULL no selecciona filas. Los valores ausentes necesitan IS NULL o IS NOT NULL. Una prueba negativa también tiene una omisión: status <> 'shipped' no incluye un estado ausente, porque su comparación es desconocida.
Si el estado ausente pertenece al grupo previsto, escribe:
WHERE status <> 'shipped' OR status IS NULL
Al añadir otra condición, agrupa toda esta alternativa con paréntesis para que ambas ramas cumplan esa condición.
La búsqueda por patrones puede abarcar más que la descripción prevista. LIKE '%lamp%' coincide con «Desk lamp» y «Clamp». El LIKE predeterminado de SQLite también ignora las mayúsculas y minúsculas de las letras inglesas, así que encuentra «Lamp shade». Un patrón es útil para encontrar posibles coincidencias, pero inspecciónalas antes de modificarlas.
Elige una comparación de listas para una lista
UPDATE orders SET status = 'on hold'
WHERE customer_id IN (
SELECT id FROM customers WHERE state = 'CA'
);
La subconsulta puede proporcionar varios identificadores de cliente; IN comprueba la pertenencia. Sustituir IN por = solicita un único resultado escalar. PostgreSQL rechaza varias filas en ese caso, mientras que SQLite utiliza solo la primera fila devuelta sin avisar y omite a los demás clientes.
Después del cambio, compara el recuento de filas afectadas con la vista previa. PostgreSQL y SQLite también permiten añadir RETURNING * para mostrar las filas afectadas. Para una escritura arriesgada, inicia una transacción antes de modificar los datos, inspecciona el resultado y después elige COMMIT o ROLLBACK.
Puntos clave
- Revisa exactamente la condición WHERE que utilizará la escritura.
- Un filtro de clave primaria identifica como máximo una fila.
- Los paréntesis hacen que las alternativas OR compartan una condición AND.
- IS NULL gestiona los valores ausentes; las comparaciones normales los omiten.
- IN acepta una lista de una subconsulta; la igualdad escalar no.
- Comprueba el recuento y el resultado antes de confirmar.
5Agrupa cambios en transacciones
Algunos cambios deben ir juntos: una transferencia necesita tanto un cargo como un abono. Las transacciones permiten tomar una sola decisión de conservar o deshacer esas sentencias, mientras que los puntos de guardado permiten volver a un punto intermedio. Seguirás los saldos a través de cambios correctos y errores, y después compararás cómo gestionan SQLite y PostgreSQL una sentencia fallida. La base de datos y la configuración del cliente importan, especialmente cuando un cambio de estructura puede confirmar trabajo anterior.
5.1 Confirma o revierte un grupo de cambios
Una transacción agrupa sentencias relacionadas en una unidad de trabajo. Decides conservar sus cambios juntos con COMMIT o deshacerlos juntos con ROLLBACK. La propiedad de todo o nada se llama atomicidad, la A de ACID.
Conserva ambos lados de una transferencia
La cuenta de Maya, con identificador 1, tiene 500,00. La cuenta de Leo, con identificador 2, tiene 120,00. Transferir 75,00 requiere dos cambios:
BEGIN;
UPDATE accounts SET balance = balance - 75.00 WHERE id = 1;
UPDATE accounts SET balance = balance + 75.00 WHERE id = 2;
SELECT id, balance FROM accounts WHERE id IN (1, 2);
COMMIT;
La primera actualización deja a Maya con 425,00. La segunda deja a Leo con 195,00. La comprobación muestra ambos saldos antes de confirmar y el total se mantiene en 620,00. Para estos saldos decimales exactos, utiliza NUMERIC de PostgreSQL; en SQLite, una versión con importes monetarios exactos almacena 50 000 y 12 000 céntimos y transfiere 7500 céntimos.
Sin una transacción explícita y con confirmación automática, la primera actualización podría hacerse permanente antes de que se ejecute la segunda. Un fallo entre ambas conservaría el cargo sin el abono. Una transacción da a las dos actualizaciones una sola decisión final de conservar o deshacer. Si falla una sentencia, gestiona el error antes de decidir que la transferencia está completa.
Comprende el límite predeterminado
Con la confirmación automática de la base de datos, cada sentencia independiente que se ejecuta correctamente se confirma como su propia transacción. Este es el comportamiento inicial habitual de SQLite, PostgreSQL, MySQL y SQL Server. Una biblioteca de programación o un cliente pueden elegir otra configuración e iniciar una transacción por ti.
BEGIN; inicia una transacción explícita en SQLite y PostgreSQL. SQLite y SQL Server también utilizan BEGIN TRANSACTION; PostgreSQL y MySQL aceptan START TRANSACTION. Oracle inicia una transacción con un cambio de datos y normalmente espera a COMMIT en herramientas como SQL*Plus, salvo que esté activada la confirmación automática.
COMMIT termina la transacción y conserva sus cambios. ROLLBACK la termina y deshace sus cambios sin confirmar. Una reversión posterior no puede traspasar una confirmación anterior.
Inspecciona y deshaz
BEGIN;
DELETE FROM orders;
SELECT * FROM orders;
ROLLBACK;
Tu conexión ve una tabla vacía en el SELECT y vuelve a ver los cinco pedidos después de la reversión. El resultado vacío era real dentro de la transacción, pero aún no era permanente. Las demás conexiones normalmente no ven los cambios sin confirmar.
Una transacción solo puede protegerte de una selección de filas equivocada si inspeccionas y decides deshacerla. SQL puede actualizar correctamente una fila no deseada: ninguna regla de la base de datos sabe qué cuenta querías indicar. Compara los identificadores, valores y recuentos devueltos con el resultado previsto antes de confirmar.
Mantén las transacciones breves y finalízalas. Las transacciones abiertas pueden mantener bloqueos que hacen esperar a otras conexiones; SQLite solo permite un escritor a la vez. Cerrar una conexión con una transacción sin terminar revierte sus cambios pendientes. Cuando una biblioteca inicia una transacción automáticamente, el programa debe invocar su método de confirmación para conservar el trabajo.
Puntos clave
- La atomicidad permite conservar o deshacer juntos los cambios relacionados.
- La confirmación automática hace permanente una sentencia independiente ejecutada correctamente.
- Tu conexión puede inspeccionar sus propios cambios pendientes.
- Tanto COMMIT como ROLLBACK finalizan la transacción.
- ROLLBACK no puede deshacer trabajo de una transacción anterior confirmada.
5.2 Gestiona errores, puntos de guardado y cambios de estructura en una transacción
Una sentencia fallida no tiene el mismo efecto en todas las bases de datos. Debes saber qué sigue pendiente antes de decidir cómo recuperarte. Un punto de guardado puede ofrecer un punto de retorno más cercano dentro de una transacción abierta.
Sigue un error
Después de la transferencia, Maya tiene 425,00 y Leo tiene 195,00. La tabla tiene CHECK (balance >= 0). Inicia una transacción y resta 30,00 a Maya: su saldo pendiente es 395,00. Después intenta restar 300,00 a Leo. Eso dejaría su saldo en -105,00, por lo que la segunda sentencia falla.
| Base de datos | Estado tras el error normal de restricción |
|---|---|
| SQLite | Se deshace la sentencia fallida; el cambio anterior de Maya sigue pendiente. |
| PostgreSQL | La transacción está fallida y se rechazan las órdenes normales posteriores. |
En SQLite, confirmar en este punto conservaría solo el cargo de Maya. En PostgreSQL, COMMIT sobre la transacción fallida la termina con una reversión. Un procedimiento claro de recuperación es ejecutar ROLLBACK, corregir la causa y volver a ejecutar las sentencias relacionadas. Ambos saldos vuelven entonces a 425,00 y 195,00 antes del intento corregido.
Deshaz una parte posterior con un punto de guardado
BEGIN;
UPDATE accounts SET balance = balance + 10 WHERE id = 1;
SAVEPOINT after_first;
UPDATE accounts SET balance = balance + 10 WHERE id = 2;
ROLLBACK TO after_first;
COMMIT;
El punto de guardado va después del aumento de Maya. ROLLBACK TO deshace el aumento posterior de Leo, pero conserva el de Maya. Los saldos finales son 435,00 y 195,00. No termina la transacción exterior; eso lo hace COMMIT.
RELEASE after_first elimina el punto de guardado sin deshacer los cambios posteriores. No es una confirmación permanente independiente dentro de la transacción exterior. PostgreSQL también permite que ROLLBACK TO sobre un punto de guardado establecido antes de un error elimine el estado fallido y continúe desde ese punto.
Comprueba si los cambios de estructura pueden revertirse
SQLite y PostgreSQL permiten CREATE TABLE, ALTER TABLE y DROP TABLE dentro de transacciones. Por ejemplo, BEGIN; DROP TABLE orders; ROLLBACK; restaura la tabla y sus filas.
El DDL normal sobre tablas permanentes en MySQL y Oracle provoca confirmaciones implícitas. Un CREATE TABLE, ALTER TABLE, DROP TABLE o TRUNCATE TABLE puede confirmar cambios anteriores pendientes además de realizar su propia operación estructural. Una reversión posterior no puede deshacer ese trabajo anterior. No supongas que una transacción que engloba un script hace que todos los dialectos de bases de datos se comporten igual.
Para un cambio de datos arriesgado, inicia la transacción, ejecuta la escritura, inspecciona sus valores y su recuento y después confirma o revierte. Por ejemplo, inspecciona los precios de iluminación después de UPDATE products SET price = ROUND(price * 1.10, 2) WHERE category = 'lighting';. Toma la decisión pronto para que la transacción no mantenga otros trabajos en espera.
Puntos clave
- Un error normal de restricción en SQLite deja pendientes los cambios anteriores de la transacción.
- Un error de PostgreSQL deja la transacción fallida hasta una reversión o recuperación a un punto de guardado.
- ROLLBACK TO deshace el trabajo posterior sin terminar la transacción.
- RELEASE elimina un punto de guardado sin confirmar la transacción exterior.
- La posibilidad de revertir DDL depende de la base de datos.
6Modifica la estructura de las tablas con ALTER TABLE y DROP TABLE
A veces las tablas necesitan un campo nuevo, un nombre más claro o una regla más estricta cuando ya contienen datos. Modificar esa estructura requiere comprobar las filas existentes y los objetos que dependen de la tabla. Añadirás y rellenarás columnas, reconocerás cuándo SQLite necesita una reconstrucción y distinguirás entre eliminar registros y eliminar su contenedor. Las dependencias también establecen el orden de trabajo al retirar tablas relacionadas.
6.1 Añade, renombra y elimina columnas con ALTER TABLE
ALTER TABLE modifica la estructura de una tabla existente y conserva sus filas. UPDATE modifica los valores que contienen esas filas. Añadir un campo de descuento requiere ALTER TABLE; aumentar los descuentos ya almacenados requiere UPDATE.
Añade y renombra campos
ALTER TABLE customers ADD COLUMN phone TEXT;
ALTER TABLE customers RENAME COLUMN phone TO mobile;
ALTER TABLE customers RENAME TO clients;
SQLite y PostgreSQL comparten estas formas. Una columna nueva asigna a las filas existentes su valor predeterminado, o NULL cuando no tiene ninguno. ADD COLUMN active INTEGER NOT NULL DEFAULT 1 asigna a cada fila actual un valor activo de 1. Añadir email TEXT NOT NULL sin valor predeterminado falla en una tabla con datos porque las filas existentes carecerían de un valor obligatorio.
SQLite admite RENAME COLUMN desde la versión 3.25.0 y DROP COLUMN desde la 3.35.0. Al renombrar, actualiza el código de la aplicación y las consultas guardadas que hagan referencia al nombre anterior. El SQL externo a la base de datos no puede descubrir automáticamente el nombre nuevo.
Rellena los datos antes de exigirlos
En PostgreSQL, añade una columna que admita nulos, rellena las filas existentes con valores adecuados y solo entonces hazla obligatoria:
ALTER TABLE customers ADD COLUMN email TEXT;
UPDATE customers SET email = 'unknown@example.com'
WHERE email IS NULL;
ALTER TABLE customers ALTER COLUMN email SET NOT NULL;
Esto ilustra cómo rellenar un campo obligatorio; no declara el correo como único. Una columna real de correo único necesita valores válidos distintos. SET NOT NULL falla si quedan valores ausentes. PostgreSQL también permite modificar un tipo con ALTER COLUMN price TYPE NUMERIC(10, 2), establecer un valor predeterminado y añadir una comprobación con nombre. Las filas existentes deben cumplir cualquier regla nueva.
Elimina un campo o reconstruye una tabla
ALTER TABLE customers DROP COLUMN mobile; elimina el campo y todos sus valores almacenados. Las dependencias pueden bloquear la operación. SQLite rechaza eliminar una columna de clave primaria, única, indexada o de clave foránea, o una utilizada por otro objeto del esquema. PostgreSQL puede eliminar objetos dependientes con CASCADE, incluida una vista que utilice la columna.
SQLite no puede modificar el tipo de una columna existente ni añadir restricciones de clave primaria, unicidad, clave foránea o comprobación a columnas existentes con un simple ALTER. La versión 3.53.0 añade ALTER COLUMN ... SET NOT NULL y DROP NOT NULL, pero no la edición general de restricciones. Una columna recién añadida puede tener una comprobación o una referencia permitida, pero no puede tener PRIMARY KEY ni UNIQUE; con las claves foráneas activadas, una referencia añadida necesita un valor predeterminado NULL.
Para un cambio más amplio en SQLite:
- Registra los índices, disparadores y vistas que deben volver a crearse. Si las claves foráneas están activadas, desactívalas antes de la transacción.
- Inicia una transacción y crea una tabla nueva con las reglas deseadas.
- Copia las filas utilizando columnas explícitas en
INSERT INTO new_products (...) SELECT ... FROM products;. - Elimina la tabla anterior y renombra la nueva como
products. - Vuelve a crear los objetos dependientes y ejecuta
PRAGMA foreign_key_check;. Resuelve cualquier problema indicado antes de confirmar. - Confirma y restablece después la aplicación de las restricciones de clave foránea si estaba activada antes.
MySQL modifica las definiciones con MODIFY COLUMN; SQL Server utiliza ALTER COLUMN. Expresa un cambio estructural con la sintaxis admitida por la base de datos de destino antes de ejecutarlo.
Puntos clave
- ALTER TABLE modifica la estructura; UPDATE modifica los valores almacenados.
- Las columnas añadidas asignan a las filas existentes un valor predeterminado o NULL.
- Rellena una columna nueva obligatoria antes de añadir NOT NULL.
- Eliminar una columna borra sus valores y puede quedar bloqueado por dependencias.
- SQLite necesita una reconstrucción para muchos cambios de tipos y restricciones.
- Las reconstrucciones deben conservar los objetos dependientes y comprobar las claves foráneas.
6.2 Elimina tablas con DROP TABLE
DROP TABLE elimina tanto el contenedor como su contenido. Después de DROP TABLE archived_orders;, las consultas no pueden leer esa tabla porque ya no existe. Sus restricciones, índices y disparadores se eliminan con ella.
Elige el nivel de eliminación
| Resultado previsto | Sentencia |
|---|---|
| Conservar la tabla y eliminar las filas seleccionadas | DELETE FROM orders WHERE ...; |
| Conservar una tabla vacía | DELETE FROM orders; |
| Vaciar rápidamente una tabla donde se admita | TRUNCATE TABLE orders; |
| Eliminar la propia tabla | DROP TABLE orders; |
DROP TABLE IF EXISTS archived_orders; evita un error si la tabla no existe. Aun así, elimina una tabla existente y sus datos. Un script de preparación que elimina y vuelve a crear tablas es destructivo cuando se ejecuta en una base de datos con registros que quieres conservar.
Respeta los vínculos entre tablas
Elimina las tablas hijas antes que las padre, invirtiendo el orden habitual de creación. En PostgreSQL, eliminar customers mientras una clave foránea de pedidos depende de ella falla. DROP TABLE customers CASCADE; también elimina la clave foránea dependiente y las vistas dependientes. La tabla de pedidos y sus filas se conservan, pero la relación con los clientes deja de exigirse.
Este CASCADE de PostgreSQL es distinto del ON DELETE CASCADE de una clave foránea. El primero elimina objetos dependientes de la base de datos durante un cambio de estructura. El segundo elimina filas hijas cuando se elimina una fila padre. Saber qué acción se utiliza evita una predicción incorrecta sobre los datos que se conservan.
Con la aplicación de las restricciones de clave foránea de SQLite activada, eliminar una tabla realiza primero una eliminación implícita de sus filas. Las filas hijas que las referencian pueden bloquearla. Si la relación declara ON DELETE CASCADE, esas filas hijas pueden eliminarse; SET NULL puede borrar sus vínculos. Por tanto, eliminar una tabla requiere prestar la misma atención a las referencias que eliminar filas, además de atender a la estructura de tabla que se elimina.
Conserva una vía de recuperación
Antes de eliminar o reconstruir una tabla con datos reales, conserva una copia utilizable. Una copia interna rápida de los datos es:
CREATE TABLE products_backup AS
SELECT * FROM products;
En SQLite y PostgreSQL, esto conserva los datos seleccionados, pero no las restricciones originales. No constituye una reconstrucción completa de la definición de la tabla. Una exportación o una copia de seguridad de la base de datos conserva los datos de recuperación fuera de la tabla que se modifica.
SQLite y PostgreSQL también permiten probar una eliminación de tabla dentro de una transacción:
BEGIN;
DROP TABLE archived_orders;
ROLLBACK;
La reversión restaura la tabla y sus filas porque la eliminación no se confirmó. Una vez confirmada, no puede revertirse ejecutando ROLLBACK después. En las bases de datos con confirmaciones implícitas de DDL, envolver la eliminación en sintaxis de transacción no proporciona esta posibilidad de deshacer. Inspecciona la base de datos de destino y las tablas implicadas antes de ejecutar un script de reconstrucción.
Puntos clave
- DROP TABLE elimina la tabla y sus filas, restricciones, índices y disparadores.
- IF EXISTS suprime el error por ausencia, no la eliminación de una tabla existente.
- Elimina las tablas hijas antes que sus tablas padre.
- DROP CASCADE de PostgreSQL elimina objetos dependientes, mientras que las tablas hijas pueden conservarse.
- Una copia de solo datos no conserva las restricciones originales.
Ejemplos de Crear y modificar tablas de base de datos
1Crea e inspecciona una tabla de productos
11 pasos
- 1IntroducciónEmpieza con un producto
Una tienda necesita registrar el identificador, nombre, precio y cantidad en existencias de un producto. La definición de una tabla asigna un campo a cada dato antes de añadir filas de productos.
Crearemos la estructura, la inspeccionaremos y después comprobaremos si los tipos conservan el significado de los valores. Los ejemplos utilizan SQLite e indican los cambios de PostgreSQL cuando afectan al resultado.
- 2ExplicaciónLee una definición de columna
En
name TEXT NOT NULL,namees el identificador del campo,TEXTdescribe su almacenamiento yNOT NULLexige un valor.La tabla enumera estas definiciones entre paréntesis, separadas por comas. El punto y coma termina la sentencia de creación. Crear la estructura es DDL; no añade filas de productos. Un
INSERTposterior proporciona esas filas. - 3EjemploCrea cuatro campos
CREATE TABLE products ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, price NUMERIC(8, 2) NOT NULL, in_stock INTEGER DEFAULT 0 );Hay cuatro definiciones de columna y tres comas de separación. SQLite genera esta clave primaria entera. PostgreSQL necesita una declaración de identidad si debe generarse un identificador omitido.
- 4ConsejoInspecciona la definición real
Utiliza
PRAGMA table_info(products);en SQL de SQLite o.schema productsen su consola de línea de comandos. En psql de PostgreSQL, utiliza\d products.La inspección detecta más que errores de sintaxis. SQLite puede interpretar la falta de una coma como parte de un nombre de tipo de varias palabras, dejando una columna donde esperabas dos.
SELECT * FROM products;muestra una tabla vacía, pero sus cero filas no verifican todas las reglas. - 5Desafío¿Esto reparará una tabla antigua?
Una tabla
productsantigua solo tieneidyname. Un script ejecutaCREATE TABLE IF NOT EXISTS products (...)con las cuatro columnas deseadas. ¿Cuántas columnas tiene después la tabla existente?---reveal---
Sigue teniendo dos.
IF NOT EXISTSomite la creación cuando el nombre ya existe. No compara las definiciones ni añade los campos que faltan. Un cambio estructural necesitaALTER TABLEo una reconstrucción deliberada. - 6ExplicaciónSepara las cantidades de los códigos
Almacena las cantidades como números para que funcionen la aritmética y la ordenación numérica. Almacena los códigos como texto cuando sus caracteres tengan significado.
El código postal estadounidense
'02139'pierde su cero inicial como entero. Los valores de texto'100','25'y'9'se ordenan en ese orden de caracteres, que es incorrecto para cantidades numéricas. La decisión depende de cómo se utilizará el campo, no de si sus ejemplos contienen cifras. - 7EjemploInterpreta la precisión y la escala
NUMERIC(8, 2)de PostgreSQL permite ocho cifras en total, con dos después de la coma. Eso deja seis antes de ella, hasta 999 999,99.Un valor de 12,345 se almacena como 12,35. Un valor de 1 234 567,00 falla porque necesita siete cifras antes de la coma. SQLite acepta la misma declaración, pero no exige esta precisión ni esta escala, por lo que esa predicción no se puede trasladar a SQLite.
- 8Idea claveConserva la exactitud de los importes monetarios
La coma flotante binaria puede introducir diferencias diminutas en la aritmética decimal.
SELECT 0.1 + 0.2 = 0.3;de SQLite devuelve falso.Utiliza
NUMERICde PostgreSQL para importes decimales exactos. En SQLite, almacena céntimos enteros: 1999 representa 19,99. EscribirNUMERIC(8, 2)en SQLite no crea un almacenamiento decimal exacto de escala fija. Los tipos aproximados siguen siendo adecuados para medidas como las temperaturas. - 9DesafíoMantén las fechas en orden
Una tabla de SQLite almacena fechas como texto. ¿Por qué cambiar
'12/01/2025'y'03/15/2026'a fechas ISO ayuda a ordenar las fechas de forma ascendente?---reveal---
Las formas ISO son
'2025-12-01'y'2026-03-15'. La comparación de texto comprueba entonces año, mes y día en ese orden y coloca primero la fecha anterior. El texto con el mes primero compara el mes antes de llegar al año y coloca estas dos fechas en un orden cronológico incorrecto. - 10DesafíoComprueba la tabla y el tipo
Un script de SQLite crea una tabla si no existe con
CREATE TABLE IF NOT EXISTS readings (qty INTEGER);. Una inserción proporciona'abc'como qty y se realiza correctamente. ¿Qué debes comprobar antes de suponer que qty siempre contiene números?---reveal---
Inspecciona la definición real, porque
IF NOT EXISTSpodría haber omitido una tabla antigua. Ten también en cuenta la afinidad normal de SQLite: una declaración de entero puede seguir almacenando texto no numérico. Una tablaSTRICTadecuada refuerza la aplicación de los tipos. - 11RepasoAdapta la estructura al uso
Una sentencia de creación define campos, tipos y reglas; una inserción proporciona los registros. Inspecciona la estructura existente en lugar de suponer que un script ejecutado correctamente creó la definición prevista.
Para cada campo, pregúntate qué debe conservarse: la aritmética numérica, los céntimos exactos, los caracteres de un identificador o el orden cronológico. Aplica el comportamiento de tipos de la base de datos de destino al predecir el resultado almacenado.
2Protege los productos y los vínculos con los clientes
13 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónComprueba los datos en la base de datos
- 2ExplicaciónAsigna una función a cada regla
- 3EjemploSigue una fila aceptada
- 4Desafío¿Un valor predeterminado corrige un NULL explícito?
- 5Idea claveUn resultado de comprobación desconocido se acepta
- 6ExplicaciónIdentifica la fila completa
- 7EjemploDeja que el sistema elija el identificador
- 8Desafío¿El siguiente identificador es un recuento de filas?
- 9ExplicaciónHaz que cada pedido encuentre a su cliente
- 10EjemploSigue una cascada
- 11DesafíoConserva los pedidos tras la eliminación
- 12DesafíoCombina las reglas necesarias
- 13RepasoComprueba valores, identidad y vínculos
3Inserta productos y copia pedidos
11 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónElige de dónde proceden las filas nuevas
- 2EjemploAsigna los valores de un producto
- 3ConsejoMantén intactos los valores literales
- 4DesafíoLee la lista explícita
- 5ExplicaciónAñade un grupo en una sola sentencia
- 6EjemploRevisa la consulta de archivo
- 7EjemploUtiliza la consulta como entrada
- 8ExplicaciónIdentifica la fila propuesta
- 9Desafío¿Conservar o sustituir?
- 10DesafíoCopia y vincula sin adivinar
- 11RepasoSigue los datos de entrada a través de la escritura
4Modifica exactamente las filas previstas
14 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónDistingue qué cambia de qué filas cambian
- 2EjemploAsigna dos valores nuevos
- 3EjemploAumenta un precio a partir de su valor anterior
- 4Desafío¿Cambiarán los demás precios?
- 5ExplicaciónElimina una fila o vacía un campo
- 6EjemploSigue los pedidos antiguos cancelados
- 7DesafíoConserva el historial de un cliente eliminado
- 8ConsejoReutiliza la condición de la vista previa
- 9EjemploAplica AND antes que OR
- 10DesafíoAplica una regla de fecha a ambos estados
- 11Idea claveUna comparación negativa omite NULL
- 12DesafíoUtiliza una lista de claves de cliente
- 13DesafíoInspecciona una actualización de todas las filas
- 14RepasoComprueba el significado y el efecto
5Conserva o deshaz un cambio completo
12 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónUna transferencia necesita dos cambios
- 2ExplicaciónEstablece un límite compartido
- 3EjemploResta el importe de la transferencia
- 4EjemploAñade e inspecciona el abono
- 5DesafíoDeshaz toda la transferencia pendiente
- 6EjemploSigue un cambio de saldo fallido
- 7ExplicaciónRecupérate según la base de datos
- 8DesafíoEvita conservar una operación incompleta
- 9EjemploMarca un punto intermedio
- 10Idea claveLiberar no es confirmar la transacción exterior
- 11Desafío¿Puede deshacerse esta eliminación de tabla?
- 12RepasoTermina con una decisión deliberada
6Modifica o elimina una tabla con datos
13 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónTrabaja con los registros existentes
- 2EjemploAñade un campo que admita nulos
- 3DesafíoHaz obligatorio un campo después de rellenarlo
- 4ConsejoActualiza cada uso externo del nombre
- 5ExplicaciónReconoce un ALTER limitado
- 6EjemploPrepara la tabla de sustitución
- 7EjemploCopia, sustituye y comprueba
- 8ExplicaciónDecide si debe conservarse la tabla
- 9EjemploSigue las dependencias de PostgreSQL
- 10DesafíoDistingue los dos significados de cascada
- 11ConsejoMantén recuperables los datos y la definición
- 12DesafíoConserva las reglas durante una reconstrucción
- 13RepasoSigue la estructura y sus dependencias
Ejercicios de Crear y modificar tablas de base de datos
Set 1: Crea tablas y realiza los primeros cambios10 Preguntas de Práctica
Pregunta 1 de 10
00481. ¿Qué tipo de almacenamiento es adecuado?Mostrar respuestaOcultar respuesta
Pregunta 2 de 10
NUMERIC(6, 2). ¿Cuál es su mayor valor positivo?Mostrar respuestaOcultar respuesta
Pregunta 3 de 10
qty INTEGER NOT NULL DEFAULT 4 CHECK (qty >= 0). Una inserción proporciona explícitamente NULL para qty. ¿Qué ocurre?Mostrar respuestaOcultar respuesta
NULL explícito se comprueba como un valor ausente proporcionado, por lo que infringe NOT NULL. El valor predeterminado de 4 se utiliza cuando se omite la columna, no cuando se envía explícitamente un valor ausente. La comprobación de no negatividad no sustituye la regla de presencia.Pregunta 4 de 10
Mostrar respuestaOcultar respuesta
Pregunta 5 de 10
supplier_id = 18, pero el proveedor 18 no existe. ¿Qué debe hacerse para insertar correctamente esa misma referencia no NULL?Mostrar respuestaOcultar respuesta
Pregunta 6 de 10
(code, name) con los valores ('R7', 'Notebook'). ¿Qué se almacena en name?Mostrar respuestaOcultar respuesta
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Pregunta 8 de 10
DELETE FROM logs; se ejecuta correctamente. ¿Qué queda?Mostrar respuestaOcultar respuesta
DELETE elimina las 12 filas y deja disponible la estructura de la tabla para inserciones posteriores. No elimina columnas ni sustituye los registros por valores ausentes. Eliminar la propia tabla requiere DROP TABLE, que es una operación estructural independiente.Pregunta 9 de 10
BEGIN, cambia una cantidad de 8 a 11 y después ejecuta ROLLBACK. ¿Qué cantidad lee esa conexión a continuación?Mostrar respuestaOcultar respuesta
Pregunta 10 de 10
Mostrar respuestaOcultar respuesta
SET NOT NULL. Exigir los valores antes de rellenarlos falla porque las filas existentes aún contendrían NULL.Set 2: Diagnostica errores habituales de SQL10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
labels de SQLite ya tiene solo las columnas id y text. Un script ejecuta CREATE TABLE IF NOT EXISTS labels (id INTEGER PRIMARY KEY, text TEXT, color TEXT);. ¿Qué ocurre con color?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
CREATE TABLE tickets (id INTEGER PRIMARY KEY, label TEXT);. No se ejecutan más sentencias. ¿Qué existe después?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
CHECK (score BETWEEN 0 AND 100). Una inserción proporciona NULL. ¿Qué ocurre?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
ON DELETE SET NULL, y project_id también es NOT NULL. Se aplican las restricciones de clave foránea. ¿Qué ocurre al eliminar el proyecto?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
CHECK (balance >= 0). Con la gestión normal de restricciones, ¿qué conservaría COMMIT?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
active INTEGER NOT NULL DEFAULT 1. ¿Qué valor de active tienen sus filas existentes?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 3: Sigue los resultados almacenados10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
NUMERIC(5, 2). ¿Qué ocurre con un valor insertado de 48,726?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
UNIQUE (room_id, start_time). Contiene (4, '09:00') y (5, '09:00'). ¿Qué ocurre al insertar (4, '10:00')?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
code TEXT PRIMARY KEY. ¿Qué regla adicional cierra la excepción histórica de SQLite que permite claves ausentes?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
qty INTEGER NOT NULL DEFAULT 6. ¿Qué inserción añade un pincel utilizando ese valor predeterminado?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
state = 'closed' OR state = 'expired' AND opened < '2026-01-01'?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
ROLLBACK TO s y confirma. ¿Qué queda?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
DROP TABLE clients CASCADE; se ejecuta correctamente. ¿Qué puede conservarse de invoices?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 4: Elige una secuencia fiable10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
CREATE TABLE t (a INTEGER b TEXT); se ejecuta correctamente. La inspección muestra solo la columna a. ¿Por qué?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
COUNT(*)?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
ON CONFLICT (code) DO UPDATE SET qty = stock.qty + excluded.qty. Después se ejecuta de nuevo la misma sentencia. ¿Qué qty se almacena?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
CREATE TABLE saved AS SELECT * FROM original;. ¿Qué debe comprobarse antes de tratar saved como una sustitución completa?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 5: Aplica las reglas a cambios combinados10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
value NUMERIC(7, 2). Insertar 6,789 se realiza correctamente. ¿Qué valor almacenado debes esperar solo a partir de esta declaración?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
label TEXT NOT NULL sin más reglas. ¿Qué ocurre cuando el valor proporcionado es una cadena vacía?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
parent_id INTEGER DEFAULT 90 REFERENCES parents(id) ON DELETE SET DEFAULT. La fila padre 90 no existe. La fila hija 12 apunta a la padre 7. ¿Qué ocurre al eliminar la fila padre 7?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
DO UPDATE SET qty = excluded.qty. ¿Qué cantidad se almacena tras ambas importaciones y qué total habría producido una suma correcta?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
customer_id = (SELECT id FROM customers WHERE eligible = TRUE). ¿Qué ocurre y qué comparación lo corrige?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
¿Te atascas con una pregunta tuya? Ayuda con Tareas
Términos Clave
A
ADD COLUMN
active INTEGER NOT NULL DEFAULT 1 asigna a los clientes existentes el valor nuevo 1 sin inserciones independientes.Afinidad de tipo
'5' en 5, pero puede conservar 'abc' como texto sin dar error.ALTER TABLE
ALTER TABLE; rellenar después los valores de teléfono utiliza UPDATE.Aplicación de las restricciones de clave foránea
PRAGMA foreign_keys = ON; en la conexión antes de una transacción para comprobar sus vínculos declarados.Asignación SET
SET in_stock = in_stock - 1 reduce el recuento almacenado, mientras que SET in_stock = 1 lo sustituye por uno.Atomicidad
AUTOINCREMENT
C
CHECK
CHECK (price > 0) rechaza un precio negativo, pero también necesita NOT NULL cuando es obligatorio proporcionar un precio.Clave compuesta
Clave foránea
Clave natural
Clave primaria
Clave sustituta
Columna de identidad
INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY proporciona identificadores nuevos sin indicar manualmente un número en cada inserción.Coma flotante
0.1 + 0.2 = 0.3 como falso porque sus literales decimales utilizan almacenamiento aproximado.COMMIT
Condición WHERE
Confirmación automática
Confirmación implícita
CREATE TABLE
CREATE TABLE labels (id INTEGER PRIMARY KEY, name TEXT); prepara una tabla antes de insertar etiquetas.CREATE TABLE AS
cheap_products contiene los productos seleccionados cuando se creó, incluso después de que cambien los precios del origen.D
DEFAULT
DEFAULT 0 asigna cero, mientras que proporcionar explícitamente NULL la deja ausente.DELETE
Dependencia
DROP CASCADE
DROP COLUMN
DROP TABLE
E
Eliminación lógica
deleted_at de un cliente conserva la fila, por lo que las consultas de clientes activos añaden deleted_at IS NULL.Escala
NUMERIC(8, 2) de PostgreSQL almacena 12,345 como 12,35 porque la escala declarada es dos.excluded
stock.qty + excluded.qty suma la cantidad de entrada propuesta a la cantidad ya almacenada.F
Fecha en formato ISO
'2026-03-15', se ordenan por año, mes y día cuando todas utilizan el mismo formato.I
Identificador
"order date" necesita comillas, mientras que order_date evita los espacios y es más fácil de reutilizar.IF EXISTS
DROP TABLE IF EXISTS archived_orders; se ejecuta correctamente cuando la tabla no existe y la elimina cuando existe.IN
Inserción de varias filas
Inserción o actualización
ON CONFLICT (sku) DO UPDATE cuando ya existe.INSERT
INSERT SELECT
INTEGER
IS NULL
WHERE phone IS NULL encuentra clientes sin número de teléfono; WHERE phone = NULL no encuentra esas filas.L
Lenguaje de definición de datos
CREATE TABLE, ALTER TABLE y DROP TABLE modifican la estructura de la base de datos en distintas etapas.Lenguaje de manipulación de datos
INSERT; corregir su estado utiliza UPDATE; eliminar su fila utiliza DELETE.Lista de columnas
(sku, name, price) hace que el primer valor proporcionado sea un SKU aunque price se declarara antes en la tabla.Literal de cadena
'O''Brien' almacena el nombre «O'Brien» con un apóstrofo en lugar de terminar el valor antes de tiempo.N
NOT NULL
NULL
NULL cuando no se conoce ningún número; IS NULL encuentra a esos clientes.Número de filas afectadas
O
ON DELETE CASCADE
ON DELETE SET NULL
P
Precedencia de operadores
Precisión de NUMERIC
NUMERIC(8, 2) de PostgreSQL permite seis cifras antes de la coma decimal y dos después, hasta 999 999,99.Punto de guardado
R
Reconstrucción de tabla
RELEASE
Restricción
Restricción con nombre
CONSTRAINT price_positive CHECK (price > 0) asigna a la regla de precio positivo un nombre para su mantenimiento posterior.RETURNING
ROLLBACK
ROLLBACK TO
after_first, establecido entre dos aumentos de saldo, elimina el aumento posterior, pero mantiene pendiente el anterior.ROUND
ROUND(price * 1.10, 2) solicita un resultado de dos decimales para un cálculo de precio en SQLite que produciría 21,989.S
Subconsulta
order_id IN (SELECT id FROM orders WHERE status = 'cancelled') para elegir las líneas relacionadas.T
Tabla de preparación
NULL mediante NULLIF(TRIM(email), '') durante la consulta de copia.Tabla hija
Tabla padre
Tipo de datos
Transacción
Transacción fallida
TRUNCATE
TRUNCATE TABLE, pero sus reglas de dependencias y transacciones siguen importando.U
UNIQUE
UNIQUE (order_id, product_id) permite el mismo producto en pedidos distintos, pero rechaza un par repetido.UPDATE
UPDATE products SET price = 22.50 WHERE id = 3; modifica un producto sin insertar una fila de producto nueva.- 1Modelo relacional
- 2Consultas con SELECT
- 3Columnas calculadas en SQL
- 4Agregación y agrupación en SQL
- 5JOIN SQL
- 6Crear y modificar tablas de base de datos
Sobre esta unidad
Crea tus propios Materiales de Estudio
Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.