【问题标题】:Can we write update and delete queries in views?我们可以在视图中编写更新和删除查询吗?
【发布时间】:2011-03-08 20:08:53
【问题描述】:

在 SQL Server 2005 中,我使用SELECT 语句创建了一些视图。我们可以在视图中写UPDATEDELETE 语句吗?

【问题讨论】:

  • 不行,不能直接在VIEW定义中写DELETE,必须是SELECT。

标签: sql-server view


【解决方案1】:

来自这篇 MSDN 文章:Modifying Data Through a View

  • 任何修改,包括 UPDATE、INSERT 和 DELETE 语句,都必须仅引用一个基表中的列。

  • 视图中正在修改的列必须直接引用表列中的基础数据。它们不能以任何其他方式派生,例如通过:

    • 聚合函数(AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VAR 和 VARP)。
    • 计算;无法从使用其他列的表达式计算该列。使用集合运算符(UNION、UNION ALL、CROSSJOIN、EXCEPT 和 INTERSECT)形成的列相当于一次计算,也不能更新。
  • 正在修改的列不受 GROUP BY、HAVING 或 DISTINCT 子句的影响。

  • 当还指定了 WITH CHECK OPTION 时,不能在视图的 select_statement 中的任何地方使用 TOP。

剩下的请看文章...

【讨论】:

  • @Srini - 不要只说“看这篇文章” - 至少做一个简短的描述,尤其是如果你想让人们对你的答案投赞成票的话。
  • @slugster- 谢谢,实际上我应该通过 SO 的常见问题解答。我现在正在做。 :)
  • 请记住,并非所有视图都是可更新的,而那些只能让您一次更新所涉及的表之一。
  • @HLGEM 除非您在视图上创建 INSTEAD OF 触发器 (stackoverflow.com/questions/6267985/…)
【解决方案2】:

**

使用视图更新数据:

** 视图可以在更新数据的查询中使用,但有一些限制。请记住,视图不是表并且不包含数据——实际的修改总是发生在表级别。视图不能用作覆盖基表中定义的任何约束、规则或引用完整性的机制。

通过视图更新数据的限制 您可以在视图中插入、更新和删除行,但有以下限制:

如果视图包含多个表之间的连接,则只能在视图中插入和更新一个表,不能删除行。

您不能根据联合查询直接修改视图中的数据。您不能修改使用 GROUP BY 或 DISTINCT 语句的视图中的数据。

所有被修改的列都受到与直接针对基表执行语句相同的限制。

不能通过视图修改文本和图像列。

不检查视图标准。例如,如果视图选择居住在巴黎的所有客户,并且修改数据以添加或编辑不具有 City = 'Paris' 的行,则数据将在基表中修改但不会显示在视图中, 除非在定义视图时使用 WITH CHECK OPTION。 更多信息请查看Article

【讨论】:

    【解决方案3】:

    更多关于斯里尼瓦斯回答的解释......

    任何修改,包括 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

    【讨论】:

      【解决方案4】:

      答案在于视图是 UPDATABLE VIEW 还是 NON UPDATABLE VIEW。

      可更新视图是包含基础表中所有非空列的视图。

      如果是这样,您对视图的更新、删除和插入查询会影响底层真实表上的数据。

      就是这样.....

      【讨论】:

        【解决方案5】:

        如果我跟随怎么办

        Create view table1_View 
        as 
           select * 
           from table1 
        
        go 
        
        delete 
        from table1_view
        

        我检查了一下,这个命令删除了 table1 中的所有数据

        【讨论】:

        • 因为它只派生自一个基表。根据 MSDN,您可以对视图执行插入、更新、删除操作,只要它是从单个表派生的。
        【解决方案6】:

        除了视图本身允许的有限更新之外,您还可以使用INSTEAD OF 触发器来执行更多涉及的更改。 INSTEAD OF 基本上可以让您拦截更新或删除,并执行几乎所有更改。参考文献:MSDN Article.

        【讨论】:

          【解决方案7】:

          如果这是您的要求,您可以从视图中删除,但您不能拥有删除信息的视图。视图是基础表中数据的一部分。只要您有权限,您就可以在视图中执行与直接对表执行相同的数据操作。

          所以你可以这样做:

          DELETE FROM my_View WHERE id = 3;
          

          When to use views
          What is a view

          【讨论】:

          • 所以我们不能这样写 create view myview as delete from emp where dept=10 end 我认为这不是写对吗
          • @Surya - 不,你不能那样做。我真的无法想象为什么你会想要。您将为此使用存储过程。
          猜你喜欢
          • 2021-04-20
          • 1970-01-01
          • 2011-06-17
          • 2020-09-18
          • 2016-02-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多