【发布时间】:2011-03-08 20:08:53
【问题描述】:
在 SQL Server 2005 中,我使用SELECT 语句创建了一些视图。我们可以在视图中写UPDATE 和DELETE 语句吗?
【问题讨论】:
-
不行,不能直接在VIEW定义中写DELETE,必须是SELECT。
标签: sql-server view
在 SQL Server 2005 中,我使用SELECT 语句创建了一些视图。我们可以在视图中写UPDATE 和DELETE 语句吗?
【问题讨论】:
标签: sql-server view
来自这篇 MSDN 文章:Modifying Data Through a View,
任何修改,包括 UPDATE、INSERT 和 DELETE 语句,都必须仅引用一个基表中的列。
视图中正在修改的列必须直接引用表列中的基础数据。它们不能以任何其他方式派生,例如通过:
正在修改的列不受 GROUP BY、HAVING 或 DISTINCT 子句的影响。
当还指定了 WITH CHECK OPTION 时,不能在视图的 select_statement 中的任何地方使用 TOP。
剩下的请看文章...
【讨论】:
**
使用视图更新数据:
** 视图可以在更新数据的查询中使用,但有一些限制。请记住,视图不是表并且不包含数据——实际的修改总是发生在表级别。视图不能用作覆盖基表中定义的任何约束、规则或引用完整性的机制。
通过视图更新数据的限制 您可以在视图中插入、更新和删除行,但有以下限制:
如果视图包含多个表之间的连接,则只能在视图中插入和更新一个表,不能删除行。
您不能根据联合查询直接修改视图中的数据。您不能修改使用 GROUP BY 或 DISTINCT 语句的视图中的数据。
所有被修改的列都受到与直接针对基表执行语句相同的限制。
不能通过视图修改文本和图像列。
不检查视图标准。例如,如果视图选择居住在巴黎的所有客户,并且修改数据以添加或编辑不具有 City = 'Paris' 的行,则数据将在基表中修改但不会显示在视图中, 除非在定义视图时使用 WITH CHECK OPTION。 更多信息请查看Article
【讨论】:
更多关于斯里尼瓦斯回答的解释......
任何修改,包括 UPDATE、INSERT 和 DELETE 语句,都必须仅引用一个基表中的列。
只要您可以管理基本表结构,就可以使用 INSTEAD OF 触发器解决此问题。 INSTEAD OF 触发器允许您覆盖视图上的 INSERT、UPDATE 或 DELETE 操作。例如,您可以在视图上定义 INSTEAD OF INSERT 触发器来替换标准 INSERT 语句。
假设您创建了以下视图:
CREATE VIEW AuthorsNames
AS
SELECT au_id, au_fname, au_lname
FROM authors
您可能希望将数据插入视图中不可见的列。为此,请在视图上创建一个 INSTEAD OF 触发器来处理插入。
CREATE TRIGGER ShowInsert on AuthorsNames
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO authors
SELECT address, au_fname, au_id, au_lname, city, contract, phone, state, zip
FROM inserted
END
使用这种方法,您可以插入多个表,但如果您要处理大量基础表,这会变得更加复杂。 Ref MSDN
【讨论】:
答案在于视图是 UPDATABLE VIEW 还是 NON UPDATABLE VIEW。
可更新视图是包含基础表中所有非空列的视图。
如果是这样,您对视图的更新、删除和插入查询会影响底层真实表上的数据。
就是这样.....
【讨论】:
如果我跟随怎么办
Create view table1_View
as
select *
from table1
go
delete
from table1_view
我检查了一下,这个命令删除了 table1 中的所有数据
【讨论】:
除了视图本身允许的有限更新之外,您还可以使用INSTEAD OF 触发器来执行更多涉及的更改。 INSTEAD OF 基本上可以让您拦截更新或删除,并执行几乎所有更改。参考文献:MSDN Article.
【讨论】:
如果这是您的要求,您可以从视图中删除,但您不能拥有删除信息的视图。视图是基础表中数据的一部分。只要您有权限,您就可以在视图中执行与直接对表执行相同的数据操作。
所以你可以这样做:
DELETE FROM my_View WHERE id = 3;
【讨论】: