日期:2014-05-18  浏览次数:20505 次

使用UNION ALL的视图为什么不能被DDL操作?
创建UNION   ALL视图
CREATE   VIEW   V_TEST
AS
SELECT   AB,   CD,   QX   FROM   TAB1
UNION   ALL
SELECT   AB,   CD,   QX   FROM   TAB2

更新此视图
UPDATE   V_TEST   SET   QX   =   6   WHERE   AB   =   'ER '

提示:
UNION   ALL   视图   'V_TEST '   不可更新,因为其定义中包含不允许的构造。

讨论,为什么这样不行哪?

------解决方案--------------------
--sqlserver 有规定
通过视图修改数据的准则
不使用 INSTEAD OF 触发器或可更新分区视图而通过视图修改数据之前,请考虑下列准则:

如果在视图定义中使用了 WITH CHECK OPTION 子句,则所有在视图上执行的数据修改语句都必须符合定义视图的 SELECT 语句中所设定的条件。如果使用了 WITH CHECK OPTION 子句,修改行时需注意不让它们在修改完成后从视图中消失。任何可能导致行消失的修改都会被取消,并显示错误信息。


SQL Server 必须能够明确地解析对视图所引用基表中的特定行所做的修改操作。不能在一个语句中对多个基础表使用数据修改语句。因此,列在 UPDATE 或 INSERT 语句中的列必须属于视图定义中的同一个基表。


对于基础表中需更新而又不允许空值的所有列,它们的值在 INSERT 语句或 DEFAULT 定义中指定。这将确保基础表中所有需要值的列都可以获取值。


在基础表的列中修改的数据必须符合对这些列的约束,如为空性、约束、DEFAULT 定义等。例如,如果要删除一行,则相关表中的所有基础 FOREIGN KEY 约束必须仍然得到满足,删除操作才能成功。

分布式分区视图(远程视图)不能使用键集驱动游标更新。此项限制可通过在基础表上而不在视图本身上声明游标得到解决。
此外,如果在视图中删除数据:

在视图定义的 FROM 子句中只能列出一个表。

------解决方案--------------------
逐个表更新吧,用事务
------解决方案--------------------
更新视图必须确保要更新的列是同一个基表的!
------解决方案--------------------
只要所做的修改只影响视图所引用的其中一个基表,就可以更新所有 SQL Server 版本内的视图(可以对其执行 UPDATE、DELETE 或 INSERT 语句)。
现在LZ建立的视图中用了UNION ALL,这样建立的视图类似分区视图。一般来说,可更新的视图中不能包含有TOP、GROUP BY、UNION(一些分区视图除外)或 DISTINCT 子句。