La respuesta corta es sí. En SQL Server, este concepto se denomina vistas actualizables y tiene sus condiciones, pero en la mayoría de casos sí posible la inserción y actualización directa de los datos de una tabla subyacente a una vista. Veamos dos ejemplos sencillos para demostrarlo. Uno con un UPDATE y otro con un INSERT.
Para estos ejemplos usaremos la vista [Sales].[vSalesPerson] de la base de datos AdventureWorks2016, si no la tienes la puedes descargar desde aquí.
La vista [Sales].[vSalesPerson] es una vista o ‘tabla virtual’ que nos muestra información de los vendedores de la compañía, como nombres, apellidos, teléfonos, direcciones y datos de ventas (Imagen 1):
Si vemos la definición de esta vista, se puede apreciar que se compone de la unión de varias tablas (tablas subyacentes) como Employee, Person, Address, StateProvince, entre otras:
CREATE VIEW [Sales].[vSalesPerson]
AS
SELECT s.[BusinessEntityID], p.[Title], p.[FirstName],
p.[MiddleName], p.[LastName], p.[Suffix],
e.[JobTitle], pp.[PhoneNumber], pnt.[Name] AS [PhoneNumberType],
ea.[EmailAddress], p.[EmailPromotion], a.[AddressLine1],
a.[AddressLine2], a.[City], [StateProvinceName] = sp.[Name],
a.[PostalCode], [CountryRegionName] = cr.[Name], [TerritoryName] = st.[Name],
[TerritoryGroup] = st.[Group], s.[SalesQuota], s.[SalesYTD],
s.[SalesLastYear]
FROM [Sales].[SalesPerson] s
INNER JOIN [HumanResources].[Employee] e
ON e.[BusinessEntityID] = s.[BusinessEntityID]
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = s.[BusinessEntityID]
INNER JOIN [Person].[BusinessEntityAddress] bea
ON bea.[BusinessEntityID] = s.[BusinessEntityID]
INNER JOIN [Person].[Address] a
ON a.[AddressID] = bea.[AddressID]
INNER JOIN [Person].[StateProvince] sp
ON sp.[StateProvinceID] = a.[StateProvinceID]
INNER JOIN [Person].[CountryRegion] cr
ON cr.[CountryRegionCode] = sp.[CountryRegionCode]
LEFT OUTER JOIN [Sales].[SalesTerritory] st
ON st.[TerritoryID] = s.[TerritoryID]
LEFT OUTER JOIN [Person].[EmailAddress] ea
ON ea.[BusinessEntityID] = p.[BusinessEntityID]
LEFT OUTER JOIN [Person].[PersonPhone] pp
ON pp.[BusinessEntityID] = p.[BusinessEntityID]
LEFT OUTER JOIN [Person].[PhoneNumberType] pnt
ON pnt.[PhoneNumberTypeID] = pp.[PhoneNumberTypeID];
GO
Para aplicar el cambio, la máquina virtual debe estar apagada.
Actualicemos datos a través de la vista!
Como primer ejemplo, actualizaremos el primer nombre (FirstName) del empleado cuyo rol es ‘North American Sales Manager’, lo cambiaremos de ‘Stephen’ a ‘Michael’ con la siguiente instrucción:
UPDATE [Sales].[vSalesPerson]
SET FirstName = 'Michael'
WHERE JobTitle = 'North American Sales Manager'
Consultando la data, vemos que el cambio se realizó con éxito:
Lo que acabamos de hacer es actualizar los datos de la tabla [Person].[Person], que es una de las tablas subyacentes a la vista [Sales].[vSalesPerson], de una manera indirecta pero más rápida; ya que usualmente podría tomarnos más tiempo diseñar un UPDATE acompañado de otros JOINS con otras tablas para poder encontrar el empleado con ese Job Title.
Insertemos datos a través de la vista!
Como segundo ejemplo, insertaremos un nuevo registro en la tabla [Phone].[PhoneNumberType], que almacena los tipos de números telefónicos (Imagen 3).
Siguiendo el ejemplo anterior, ejecutaremos el INSERT desde la vista [Sales].[vSalesPerson]. De esta manera:
INSERT INTO [AdventureWorks2016].[Sales].[vSalesPerson] (PhoneNumberType)
VALUES ('Office');
GO
Si lo hemos insertado correctamente, la tabla [Phone].[PhoneNumberType] debe verse así al consultarla:
En este caso, la inserción de un nuevo registro en la tabla fue posible porque los demás campos que no aparecen en el INSERT (como PhoneNumberTypeID y ModifiedDate) tienen valores por default de IDENTITY() y GETDATE(), respectivamente.
Conclusiones
Hemos aprendido el concepto de vistas actualizables, sus restricciones; y cómo es posible insertar y actualizar data directamente desde una vista en vez de hacerlo sobre sus tablas subyacentes, con el potencial de simplificar nuestras transacciones.
Si tienes alguna duda, comentarios o sugerencias, me puedes enviar un correo a bitácoradeundba@gmail.com.