问题
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?
回答1:
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 suggest1) 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 :).
来源:https://stackoverflow.com/questions/21497808/how-can-i-perform-dml-operations-in-sql-server