如何在SQL Server中执行DML操作?

时间:2014-02-01 12:06:28

标签: sql sql-server dml

我想知道如何对由多个表组成的视图执行DML操作。

IE中。如果我有一个加入三个表的视图,我可以在这个视图上执行DMLUPDATEDELETE操作吗?

1 个答案:

答案 0 :(得分:3)

  

如果DML操作(更新/删除/插入)只影响一个   您的View的基础表有可能做到这一点。如果   该操作会影响您需要使用多个表Instead of Triggers

     

而不是触发器,触发而不是触发动作和   为你做的工作。例如,如果你的更新/插入/删除   影响多个基础表。而不是触发器将启动   而不是你的DML动作,并对底层进行更改   表作为单独的操作。

     

If your DML operation only effects One underlying Table you can do it的规则并非总是如此。如果您有基于更多的视图   比我建议的一张桌子

     

1)直接对基础表进行更改(首选   方法)。
2)使用而不是触发器(有点复杂   方法)。

要了解有关触发器的更多信息 Read Here

示例

创建这两个表EmployeesDepartment

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

查看基于这两个表格

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

结果视图集

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         ║
╚═══════╩═══════════════╩═════════════════╝

执行更新

即使UPDATE仅影响一个基础表。

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         ║
╚═══════╩═══════════════╩═════════════════╝

目标更新是将ID为Sara's部门的emlpoyee更新为HR,但它也将John的部门更新为HR。

在这种情况下,即使我只更新了单个基础表,也允许更新语句成功执行,但更新更新语句更新实际的Departments表而不是视图本身

现在,如果您从Departments表中选择数据,您将看到

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.
╚════════╩════════════╝

我做了所有这些,因为当您针对多个底层表发出更新语句时,它会抛出错误并显示Update is not allowed because it effects multiple tables。在这种情况下,sql server允许我们更新表,因为没有出错,但实际上它出现了可怕的错误,你刚搞砸了整个数据。

因此我会说如果你有一个基于多个表的视图选择我上面提到的选项之一,并且不对视图本身做任何DML操作。我希望我已经清除了雾:)。