16

我有一个看起来与此类似的观点,

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 中的字段(这是我目前所能实现的)在这种情况下,“基表”的定义是否不会扩展到任何后续连接的表?

4

4 回答 4

16

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

如果您尝试在同一更新语句中更新来自不同表的列,则会收到错误消息。

Msg 4405, Level 16, State 1, Line 7
View or function 'v_ViewName' is not updatable because the modification affects multiple base tables.
于 2011-09-02T09:17:53.037 回答
5

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

一般规则

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

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

删除规则

只要连接中只有一个保留键的表,就可以删除连接视图中的行。如果视图是使用 WITH CHECK OPTION 子句定义的,并且键保留表被重复,则无法从视图中删除行。

INSERT 规则 INSERT 语句不得显式或隐式引用非键保留表的列。如果使用 WITH CHECK OPTION 子句定义连接视图,则不允许使用 INSERT 语句。

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

于 2011-09-02T08:48:04.183 回答
0

我认为您可以看到如果 25 中有一行StaffStaffIdStaffPreferences. 您可以做各种正确的事情(保持这是一个表的外观,执行插入StaffPreferences;拒绝更新;等等)。

我认为此时,SQL Server 引擎将放弃,您必须编写一个触发器来实现您想要的行为(无论是什么。您需要考虑连接工作/不工作的所有情况)

于 2011-09-02T09:19:48.483 回答
-1

这是我解决它的方法。

在我的情况下,它是表,而不是视图,但我需要在引用表中的数据构造中找到引用该表的模式 id,比如调用our_schema.

我运行了以下内容:

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

这给了我 778 的 ID(示例)

然后我查看了这个 ID 以 T、B 或 H 为前缀的位置。

在我们的例子中,我们有存储数据的 Table、Base 和 History 表。

然后我跑了:

delete from T778
delete from B778
delete from H778

这使我可以删除数据并绕过该限制。

于 2015-06-05T18:39:05.720 回答