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

4

我正在使用SQL Server Management Studio 2008。

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

我无法知道,从哪个表中获取这个空记录。

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

有人可以帮我从我的视图和所有相关表中删除这个空记录吗?

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

当我尝试从视图中删除此记录时,它会显示错误,如下所示:

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

嗯,SQL Server 是正确的,视图通常是只读的(如果您的更新仅更改一个表中的数据,则可以工作)。很抱歉,但您必须展示您的视图定义(以及可能是底层表的定义)。 - pbhd
从viewGetProgressOverview中删除subscriptionID为空的记录...我正在尝试运行这个查询。 - Hiral Bavisi
@pbhd和var___。我无法粘贴查询,因为它太长了。 - Hiral Bavisi
请在你的问题中粘贴DDL视图。 - Ravi
在您贴出视图DDL之前,我们无法得到确切的问题。尽管如此,您可以遵循这个链接:http://stackoverflow.com/questions/6267985/unable-to-perform-delete-on-view-sql-server-2005 - Ravi
显示剩余2条评论
4个回答

7
如果您在SQL中创建了一个基于单个表的视图,则对视图执行的DML操作会自动传播到基础表。然而,当您连接多个表以创建视图时,如果您对视图执行DML语句,则会遇到以下错误:
Msg 4405, Level 16, State 1, Line 1
View or function 'ViewName' is not updatable because the modification affects
multiple base tables.

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

在连接视图上进行任何插入、更新或删除操作只能修改一个基本表。

更新规则

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

删除规则

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

插入规则

INSERT语句不能明确或隐含地引用非保留键表的列。如果使用WITH CHECK OPTION子句定义了连接视图,则不允许使用INSERT语句。

参考:-

插入到视图 - 触发器之外 - SQL Server

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


@HiralBavisi 在这种情况下,您可以使用存储过程或触发器。如果需要更多信息,请参考第一个链接。如果您仍然有任何问题,请告诉我。 - Ravi
@HiralBavisi 告诉我一个事情,你在视图中用了什么类型的连接查询(我的意思是外部还是内部)? - Ravi

1

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

where subscriptionID IS NOT NULL

这不是解决方案,但是如果OP对此满意的话,那就可以。 - Ravi
@AD现在我不知道它是否对我有帮助,但您可以告诉我如何隐藏单行吗?我应该试一下。 - Hiral Bavisi
如果可能的话,请与我们分享视图查询,必要时进行混淆。就我个人而言,我认为可更新的视图违背了视图的目的(这里也有一个很好的讨论:https://dev59.com/lnVC5IYBdhLWcg3wsTRi),视图适用于更安全的只读数据访问。 - Andrei Drynov

0

如果您的视图定义包含外连接,则数据库管理系统可能会制造那些空值。如果您的视图需要外连接,则没有真正的方法可以避免这些空值。如果保留它们,那么您将看到空值。如果隐藏它们,那么您就打败了外连接的目的。

唯一符合所需外连接条件的去除空值的方式是从保留表中删除一行。(其键导致 DBMS 制造空值的行。)

唯一可能阻止您确定保留表中有问题行的事情是视图不包括该表的任何候选键。逐个从每个表添加一个候选键,直到找到正确的键为止。您不需要更改视图定义来执行此操作;只需将视图的 SELECT 语句复制到 SQL 窗口即可。


我知道如果我从表中删除它,就可以解决这个问题。但是我甚至找不到它在哪里。这里有11个连接的表,但是没有一个有问题。:( - Hiral Bavisi
您的视图缺少候选键。我已编辑我的答案。 - Mike Sherrill 'Cat Recall'

0

我需要采取的最后一步是使用我的最新备份重新创建整个数据库,并在该备份之后重新创建我创建的表格。 现在,我的问题也得到了解决。 感谢大家的回复和帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接