Vistas actualizables
Una vista actualizable es una vista sobre la que puedes ejecutar sentencias INSERT, UPDATE o DELETE, y los cambios se aplican directamente a la tabla subyacente. No todas las vistas son actualizables; MySQL requiere que la vista cumpla ciertas condiciones para permitir modificaciones.
Requisitos
Una vista es actualizable cuando su consulta:
| Requisito | Descripción |
|---|---|
| Sin funciones de agregación | No usa COUNT, SUM, AVG, MIN, MAX |
| Sin DISTINCT | No usa SELECT DISTINCT |
| Sin GROUP BY | No agrupa filas |
| Sin HAVING | No filtra grupos |
| Sin UNION | No combina resultados |
| Sin subconsultas en SELECT | No tiene subconsultas en la lista de columnas |
| Columnas de una sola tabla | Las columnas modificadas pertenecen a una tabla |
Vista actualizable: ejemplo
-- Vista simple sobre una tabla, sin agregaciones ni joins
CREATE VIEW v_productos_electronicos AS
SELECT id, nombre, precio, stock
FROM productos
WHERE categoria_id IN (6, 7, 8);
SELECT * FROM v_productos_electronicos;| id | nombre | precio | stock |
|---|---|---|---|
| 1 | iPhone 15 Pro | 1299.99 | 45 |
| 2 | Samsung Galaxy S24 | 899.99 | 62 |
| 3 | Google Pixel 8 | 699.00 | 38 |
| 4 | Xiaomi 14 | 599.99 | 80 |
| 5 | MacBook Air M3 | 1399.00 | 25 |
| 6 | Lenovo ThinkPad X1 | 1549.00 | 18 |
| 7 | ASUS ROG Zephyrus | 1899.99 | 12 |
| 8 | Funda iPhone silicona | 49.99 | 200 |
| 9 | Cargador USB-C 65W | 35.99 | 150 |
| 10 | Cable USB-C a Lightning | 19.99 | 300 |
UPDATE a través de la vista
-- Actualizar el precio a través de la vista
UPDATE v_productos_electronicos SET precio = 1249.99 WHERE id = 1;
-- Verificar el cambio en la tabla real
SELECT nombre, precio FROM productos WHERE id = 1;| nombre | precio |
|---|---|
| iPhone 15 Pro | 1249.99 |
El UPDATE se aplicó directamente a la tabla productos.
-- Restaurar el precio original
UPDATE v_productos_electronicos SET precio = 1299.99 WHERE id = 1;DELETE a través de la vista
-- Insertar un producto de prueba
INSERT INTO productos (nombre, descripcion, precio, stock, categoria_id)
VALUES ('Producto test', 'Temporal', 9.99, 0, 6);
-- Verificar que aparece en la vista
SELECT id, nombre FROM v_productos_electronicos WHERE nombre = 'Producto test';| id | nombre |
|---|---|
| 31 | Producto test |
-- Eliminar a través de la vista
DELETE FROM v_productos_electronicos WHERE nombre = 'Producto test';La fila se elimina de la tabla productos.
INSERT a través de la vista
-- INSERT a través de la vista
INSERT INTO v_productos_electronicos (id, nombre, precio, stock)
VALUES (31, 'Auriculares BT', 79.99, 50);El INSERT funciona, pero la fila insertada puede no ser visible a través de la vista si no cumple el WHERE de la vista. En este caso, no especificamos categoria_id, así que será NULL y no aparecerá en la vista.
Vista NO actualizable: con JOIN
CREATE VIEW v_pedidos_completos AS
SELECT
p.id AS pedido_id,
c.nombre AS cliente,
p.estado,
p.total
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id;
-- Esto falla: la vista tiene JOIN
-- UPDATE v_pedidos_completos SET estado = 'entregado' WHERE pedido_id = 1;
-- Error: Can not modify more than one base table through a join viewSin embargo, si el UPDATE solo modifica columnas de una tabla:
-- Esto SÍ funciona: solo modifica columnas de pedidos
UPDATE v_pedidos_completos SET estado = 'entregado' WHERE pedido_id = 13;
-- Restaurar
UPDATE v_pedidos_completos SET estado = 'pendiente' WHERE pedido_id = 13;Vista NO actualizable: con agregación
CREATE VIEW v_stats_categoria AS
SELECT
categoria_id,
COUNT(*) AS total_productos,
AVG(precio) AS precio_medio
FROM productos
GROUP BY categoria_id;
-- Esto falla: la vista usa GROUP BY y funciones de agregación
-- UPDATE v_stats_categoria SET precio_medio = 100 WHERE categoria_id = 6;
-- Error: The target table is not updatableVerificar si una vista es actualizable
SELECT TABLE_NAME, IS_UPDATABLE
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = 'tienda_mysql';| TABLE_NAME | IS_UPDATABLE |
|---|---|
| v_productos_electronicos | YES |
| v_pedidos_completos | YES |
| v_stats_categoria | NO |
Limpieza
DELETE FROM productos WHERE nombre = 'Auriculares BT';
DROP VIEW IF EXISTS v_productos_electronicos;
DROP VIEW IF EXISTS v_pedidos_completos;
DROP VIEW IF EXISTS v_stats_categoria;En el siguiente artículo veremos los algoritmos de procesamiento que MySQL usa para ejecutar las vistas.
Escrito por Eduardo Lázaro
