【问题标题】:How can I perform DML operations in SQL Server?如何在 SQL Server 中执行 DML 操作?
【发布时间】:2014-02-25 04:40:29
【问题描述】:

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

即。如果我有一个连接三个表的视图,有没有办法可以在这个视图上执行DML 操作,如UPDATEDELETE 等?

【问题讨论】:

  • 为什么不更新基础表?

标签: sql sql-server dml


【解决方案1】:

如果 DML 操作(更新/删除/插入)只影响一个 您的视图的基础表您可以做到这一点。如果 多个表的操作效果需要使用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 为 1 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 操作。我希望我已经消除了迷雾:)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    相关资源
    最近更新 更多