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:

RequisitoDescripción
Sin funciones de agregaciónNo usa COUNT, SUM, AVG, MIN, MAX
Sin DISTINCTNo usa SELECT DISTINCT
Sin GROUP BYNo agrupa filas
Sin HAVINGNo filtra grupos
Sin UNIONNo combina resultados
Sin subconsultas en SELECTNo tiene subconsultas en la lista de columnas
Columnas de una sola tablaLas 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;
idnombrepreciostock
1iPhone 15 Pro1299.9945
2Samsung Galaxy S24899.9962
3Google Pixel 8699.0038
4Xiaomi 14599.9980
5MacBook Air M31399.0025
6Lenovo ThinkPad X11549.0018
7ASUS ROG Zephyrus1899.9912
8Funda iPhone silicona49.99200
9Cargador USB-C 65W35.99150
10Cable USB-C a Lightning19.99300

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;
nombreprecio
iPhone 15 Pro1249.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';
idnombre
31Producto 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 view

Sin 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 updatable

Verificar si una vista es actualizable

SELECT TABLE_NAME, IS_UPDATABLE
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = 'tienda_mysql';
TABLE_NAMEIS_UPDATABLE
v_productos_electronicosYES
v_pedidos_completosYES
v_stats_categoriaNO

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