¿Se Pueden Modificar Datos De Una Tabla A Través De Una Vista?

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):

sql server updatable views
Imagen 1. Vista [Sales].[vSalesPerson]

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
You can also use Profiler to detect deadlocks

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:

sql server updatable views
Imagen 2. Vista [Sales].[vSalesPerson] actualizada

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).

sql server updatable views
Imagen 3. Tabla [Phone].[PhoneNumberType]

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:

sql server updatable views
Imagen 4. Tabla [Phone].[PhoneNumberType] modificada

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.

Deja un comentario