Question

I want to know how I can perform DML operations on a view composed of more than 1 table.

Ie. if I have a view that joins three tables, is there a way I can can perform DML operations like UPDATE, DELETE, etc. on this view?

Was it helpful?

Solution

if the DML operation (Update/Delete/Insert) effects only one underlying table of your View the chances are you can do it. if the the operation effects more than one table you need to use Instead of Triggers.

Instead of triggers, triggers instead of the triggering action and does the job for you. for instance if your Update/insert/delete effects multiple underlying table. Instead of trigger will fire up instead of your DML action and makes changes to the underlying tables as separate operations.

The rule that If your DML operation only effects One underlying Table you can do it, is not always true. if you have a view based on more than one table I would suggest

1) making changes directly to the underlying tables (Preferred Method).
2) Using Instead of triggers (A bit complex approach).

To learn more about instead of triggers Read Here

Example

Create these two table Employees and Department

CREATE TABLE Employees(ID INT, NAME VARCHAR(10), DeptID INT)
GO
INSERT INTO Employees VALUES 
(1, 'Sara', 1),(2, 'John', 1),(3, 'Sam', 2)
,(4, 'Mike', 3),(5, 'Josh', 2)
GO

CREATE TABLE Department(DeptID INT, Department VARCHAR(10))
GO
INSERT INTO Department VALUES
(1, 'IT'),(2, 'Finance'),(3, 'HR')
GO

View Based on these two tables

CREATE VIEW Emp_Details
AS
SELECT E.ID         AS [EmpID]
      ,E.Name       AS [Employee Name]
      ,D.Department AS [Department Name]
FROM Employees E INNER JOIN Department D
ON E.DeptID = D.DeptID

Result Set of View

SELECT * FROM dbo.Emp_Details

╔═══════╦═══════════════╦═════════════════╗
║ EmpID ║ Employee Name ║ Department Name ║
╠═══════╬═══════════════╬═════════════════╣
║     1 ║ Sara          ║ IT              ║
║     2 ║ John          ║ IT              ║
║     3 ║ Sam           ║ Finance         ║
║     4 ║ Mike          ║ HR              ║
║     5 ║ Josh          ║ Finance         ║
╚═══════╩═══════════════╩═════════════════╝

Do an Update

even though UPDATE only effects One underlying table.

UPDATE dbo.Emp_Details
SET [Department Name] = 'HR'
WHERE [EmpID] = 1

SELECT * FROM dbo.Emp_Details

╔═══════╦═══════════════╦═════════════════╗
║ EmpID ║ Employee Name ║ Department Name ║
╠═══════╬═══════════════╬═════════════════╣
║     1 ║ Sara          ║ HR              ║ --<-- This was intended Update
║     2 ║ John          ║ HR              ║ --<-- this has also updated not intended
║     3 ║ Sam           ║ Finance         ║
║     4 ║ Mike          ║ HR              ║
║     5 ║ Josh          ║ Finance         ║
╚═══════╩═══════════════╩═════════════════╝

The intended update was to UPDATE emlpoyee with ID 1 Sara's department to HR but it has also update John's Department to HR.

In this case even though I was only updating a single underlying table, The update statement was allowed and executed successfully but the update update statement update the actual Departments table not the view itself

Now if you select data from Departments table you will see

SELECT * FROM Department

╔════════╦════════════╗
║ DeptID ║ Department ║
╠════════╬════════════╣
║      1 ║ HR         ║ --<-- It has actually updated the DeptID in this table
║      2 ║ Finance    ║    -- so all the employees with DeptID 1 is shown as 
║      3 ║ HR         ║    -- HR employees.
╚════════╩════════════╝

I did all this because when you Issue an update statement against multiple Underlying tables it throws and error saying Update is not allowed because it effects multiple tables. in this case sql server allowed us to update the table as nothing went wrong but as matter of fact it went horribly wrong and you have just messed up the whole data.

Therefore I would say If you have a view based on multiple table pick one of the option I have mentioned above and do not do any DML operation against the view itself. I hope I have cleared the fog :).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top