¿Alguna vez te has encontrado en una situación en la que agregaste una columna a una tabla referenciada por una vista en SQL Server, pero la columna agregada no apareció en el conjunto de resultados cuando ejecutaste la vista? Esto puede ser una experiencia frustrante, pero afortunadamente, hay soluciones para este problema.
Cuando se crea una vista en SQL Server, los metadatos de las columnas de la tabla referenciada (nombre de la columna y posición ordinal) se persisten en la base de datos. Cualquier cambio realizado en la(s) tabla(s) base referenciada(s), como el reordenamiento de columnas o la adición de una nueva columna, no se reflejará en la vista hasta que se altere, se vuelva a crear o se actualice la vista.
Echemos un vistazo a un ejemplo para entender esto mejor:
CREATE TABLE dbo.Customer
(
customer_id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
firstname NVARCHAR(40) NOT NULL,
lastname NVARCHAR(40) NOT NULL,
birthdate DATETIME NULL
)
INSERT INTO dbo.Customer (firstname, lastname, birthdate)
VALUES ('George', 'Washington', '1950-07-01')
INSERT INTO dbo.Customer (firstname, lastname, birthdate)
VALUES ('James', 'Madison', '1948-11-09')
INSERT INTO dbo.Customer (firstname, lastname, birthdate)
VALUES ('Alexander', 'Hamilton', '1970-03-02')
CREATE VIEW dbo.v_Customer
AS
SELECT * FROM dbo.Customer
Ejecutar la vista usando SELECT * FROM dbo.v_Customer nos dará el siguiente resultado:
customer_id | firstname | lastname | birthdate
------------|------------|------------|------------
1 | George | Washington | 1950-07-01
2 | James | Madison | 1948-11-09
3 | Alexander | Hamilton | 1970-03-02
Ahora, digamos que surge un nuevo requisito comercial y necesitamos agregar una columna “last_order_date” a la tabla para realizar un seguimiento de la última vez que un cliente ordenó stock de nuestro almacén:
ALTER TABLE dbo.Customer
ADD last_order_date DATETIME NULL
EXEC sp_help [dbo.Customer]
Como podemos ver, se ha agregado la columna “last_order_date” a la tabla. Sin embargo, si ejecutamos nuestra vista nuevamente, obtendremos el mismo resultado que antes del cambio de columna. Esto sucede porque la información de metadatos de la vista sobre la tabla debe actualizarse y no se mantiene automáticamente.
Para actualizar la vista, tenemos algunas opciones:
- Alterar la vista usando una declaración
ALTER VIEW. - Recrear la vista usando las declaraciones
DROP VIEWyCREATE VIEW. - Actualizar la vista utilizando el procedimiento almacenado del sistema
sp_refreshview.
Mi preferencia es utilizar sp_refreshview ya que me ahorra tener que buscar la vista y emitir un DROP VIEW/CREATE VIEW y volver a otorgar permisos o emitir una declaración ALTER VIEW:
EXEC sp_refreshview [dbo.v_customer]
SELECT * FROM dbo.v_customer
Ahora, si ejecutamos la vista nuevamente, podemos ver que devuelve todas las columnas, incluida la recién agregada.
Para evitar este tipo de problemas en el futuro, se recomienda evitar el uso de SELECT * en las definiciones de tus vistas. Al definir explícitamente una lista de columnas, te verás obligado a cambiar cualquier vista que haga referencia a tablas que requieran un cambio. Otra opción es emitir tus declaraciones CREATE VIEW con la opción SCHEMABINDING. Las vistas definidas con esta opción no permiten la sintaxis SELECT * y recibirás un error si lo intentas. De esta manera, puedes evitar que los desarrolladores menos experimentados utilicen esta sintaxis y causen problemas.
Si tienes curiosidad sobre cómo se almacenan los metadatos de tu vista, puedes echar un vistazo a la vista INFORMATION_SCHEMA.COLUMNS, donde se guarda la información de las columnas de la vista junto con la información de las columnas de la tabla.
Al seguir estas mejores prácticas y comprender cómo actualizar vistas en SQL Server, puedes asegurarte de que tus vistas siempre reflejen los últimos cambios realizados en las tablas subyacentes.