【问题标题】:SQL Updatable View with joined tables带有连接表的 SQL 可更新视图
【发布时间】:2011-11-09 00:16:23
【问题描述】:

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

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

【问题讨论】:

    标签: sql-server view sql-update sql-view


    【解决方案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
    

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • UPDATE 语句运行它只会显示“(0 行受影响)”,如果我将其更改为更新 StaffName,我会受到 1 行影响。
        • @Rob2211 这可能意味着StaffPreferencesStaffID = 25 中没有行
        • 天哪,我不觉得害羞吗!我一定认为它会创建该行,但到底为什么会这样!
        • 除此之外,如果您创建两个手动执行插入操作的INSTEAD OF INSERTINSTEAD OF UPDATE 触发器,则可以更新多行。
        【解决方案4】:

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

        一般规则

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

        UPDATE 规则 连接视图的所有可更新列必须映射到 保留键的表的列。请参阅“密钥保留表” 密钥保留表的讨论。如果视图是用 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

        【讨论】:

        • All updatable columns of a join view must map to columns of a key-preserved table. MS SQL 是这样吗,而不仅仅是 oracle?
        • 据我所知,这也适用于 MSSQL。
        • “通则”的原因是什么?会不会导致某种病理状态?
        猜你喜欢
        • 2023-04-01
        • 2011-10-11
        • 2013-07-27
        • 2011-09-22
        • 1970-01-01
        • 1970-01-01
        • 2014-09-26
        • 1970-01-01
        相关资源
        最近更新 更多