带有连接表的SQL可更新视图

时间:2011-09-02 08:39:32

标签: sql-server sql-update

我有一个类似于此的视图,

SELECT  dbo.Staff.StaffId, dbo.Staff.StaffName, dbo.StaffPreferences.filter_type
FROM    dbo.Staff LEFT OUTER JOIN
        dbo.StaffPreferences ON dbo.Staff.StaffId = dbo.StaffPreferences.StaffId

我正在尝试使用

更新StaffPreferences.filter_type
UPDATE vw_Staff SET filter_type=1 WHERE StaffId=25

我在MSDN文章

中已经阅读过这篇文章
  

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

这是否意味着我只能更新dbo.Staff中的字段(这是我当前可以实现的)在这种情况下,“基表”的定义是否不会扩展到任何后续连接的表?

编辑:这是MS SQL

4 个答案:

答案 0 :(得分:12)

您的语句应该可以正常工作,因为您只是从一个表(StaffPreferences)修改列。

如果您尝试在同一更新语句中更新不同表中的列,则会出错。

Msg 4405, Level 16, State 1, Line 7
View or function 'v_ViewName' is not updatable because the modification affects multiple base tables.

答案 1 :(得分:5)

  

可更新连接视图的规则如下:

     

一般规则

     

连接视图上的任何INSERT,UPDATE或DELETE操作都只能修改   一次一个基础基表。

     

更新规则连接视图的所有可更新列都必须映射到   密钥保留表的列。有关a,请参阅“密钥保留表”   讨论密钥保留表。如果视图定义为   WITH CHECK OPTION子句,然后是所有连接列和所有列   重复的表是不可更新的。

     

删除规则

     

只要只有一行,就可以删除连接视图中的行   连接中的密钥保留表。如果使用WITH定义视图   CHECK OPTION子句和密钥保留表重复,然后   无法从视图中删除行。

     

INSERT规则 INSERT语句不能显式或   隐式引用非键保留表的列。如果   join视图是使用WITH CHECK OPTION子句INSERT定义的   不允许发表声明。

http://download.oracle.com/docs/cd/B10501_01/server.920/a96521/views.htm#391

答案 2 :(得分:0)

我认为如果Staff中有一行StaffId 25但StaffPreferences中没有匹配的行,则可以看到可能出现的一些问题。您可以做各种正确的事情(保留这是一个表格的外观,在StaffPreferences中执行插入;拒绝更新;等等。)

我认为在这一点上,SQL Server引擎会放弃,你必须编写一个触发器来实现你想要的行为(无论可能是什么。你需要考虑所有加入工作的情况/不工作)

答案 3 :(得分:0)

以下是我如何解决它。

在我的情况下,它是表,而不是视图,但我需要找到引用参考表中数据构造中的表的模式ID,比如称为our_schema

我运行了以下内容:

select schemaid from our_schema where name = "MY:Form"

这给了我778(例子)的身份

然后我查看了此ID显示的前缀为T,B或H.

在我们的例子中,我们有表,数据存储的表,基表和历史表。

然后我跑了:

delete from T778
delete from B778
delete from H778

这允许我删除数据并绕过该限制。