从视图及其所有相关表中删除记录

Posted

技术标签:

【中文标题】从视图及其所有相关表中删除记录【英文标题】:Delete a record from a view and from all its related tables 【发布时间】:2012-12-25 11:59:48 【问题描述】:

我正在使用 SQL Server Management Studio 2008。

我想从一个视图中删除一条记录,该视图显示该记录中所有列的空值。

我不知道,我从哪个表得到这个空记录。

我检查了所有为视图连接的表,但没有一个表包含空记录。

谁能帮我从我的视图和所有相关表中删除这条空记录..?

因为我在许多其他页面中使用此视图,它会在每个页面中创建带有 null 值的错误。

当我尝试从视图中删除此记录时,它会显示类似的错误

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

【问题讨论】:

嗯,sql server 是对的,视图“通常”是只读的(如果您的更新仅更改一个表中的数据,它可以工作)。很抱歉,但您必须展示您的视图定义(可能还有基础表的定义) 从 viewGetProgressOverview 中删除 subscriptionID 为空..我正在尝试运行此查询.. @HiralBavisi 不是 DML,您的 DDL 声明供查看 可能相关问题,***.com/questions/7281054/… @pbhd 和 var___ 我无法粘贴查询,因为它太长了.. 【参考方案1】:

如果您在 SQL 中创建了基于单个表的视图 – 您在视图上执行的 DML 操作会自动执行 传播到基表。

但是,当您连接多个表以创建视图时,您 如果您针对 查看

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

更新加入视图的规则如下:

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

更新规则

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

删除规则

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

插入规则

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

参考:-

Inserting to a View – INSTEAD OF TRIGGER – SQL Server

Sql updatable view with joined tables

【讨论】:

@HiralBavisi 在这种情况下,要么使用存储过程,要么使用触发器。有关更多信息,您可以参考第一个链接。而且,如果您仍有任何问题,请告诉我。 @HiralBavisi 告诉我一件事,你用什么类型的连接查询来查看(我的意思是外部或内部)?【参考方案2】:

你不能从视图的结果中隐藏记录吗?例如

where subscriptionID IS NOT NULL

【讨论】:

这不是解决方案,但是 OP 会对此感到满意,然后就可以了。 @ADNow 我不知道它对我有没有帮助,但你能告诉我如何隐藏一行..我应该尝试一次.. 如果可能,请与我们分享视图查询,如有必要,请对其进行混淆处理。就我个人而言,我认为可更新视图违背了视图的目的(这里也有很好的讨论:***.com/questions/214132/what-are-views-good-for),视图有利于更安全地以只读方式访问数据。【参考方案3】:

如果您的视图定义包含外连接,则 dbms 可能制造那些空值。如果您的视图需要外连接,那么实际上没有任何方法可以绕过这些空值。如果你保留它们,那么你会看到空值。如果你隐藏它们,那么你就违背了外连接的目的。

删除它们与所需外连接一致的唯一方法是从保留的表中删除一行。 (其键导致 dbms 制造空值的行。)

唯一可以阻止您识别保留表中的麻烦行的是视图不包含该表的任何候选键。从每个表中添加一个候选键,一次一个,直到找到正确的键。您无需更改视图定义即可执行此操作;只需将视图的 SELECT 语句复制到 SQL 窗口即可。

【讨论】:

我知道如果我从导致它的表中删除它,我可以解决它..但我什至找不到它..有11个表加入了这个..但没有任何问题..:( 您的视图缺少候选键。编辑了我的答案。【参考方案4】:

我需要采取的最后一步是使用我上次备份重新创建洞数据库并重新创建我在该备份之后创建的表。 现在它也解决了我的问题。 谢谢大家的回复和帮助..

【讨论】:

以上是关于从视图及其所有相关表中删除记录的主要内容,如果未能解决你的问题,请参考以下文章

从具有多个基表的视图中删除记录的最有效方法?

ASP.NET :- 使用单一视图从两个表中删除记录

删除记录而不删除另一个 Access 表中的相关记录

删除所有表中的所有记录

如果所有记录都等于特定值,则从一个表中删除记录

删除表中的所有记录 ID从1开始