通过视图修改数据
您可以通过视图修改基础基表的数据,其方式与使用 UPDATE、INSERT 和 DELETE 语句,或使用 bcp 实用工具和 BULK INSERT 语句在表中修改数据一样。 但是,以下限制应用于更新视图,但不应用于表:
注意 |
---|
下列某些限制不适用于分区视图,且没有任何限制适用于通过 INSTEAD OF 触发器应用的更新。 有关详细信息,请参阅本主题后面的“通过视图修改数据的其他选择”。 |
任何修改(包括 UPDATE、INSERT 和 DELETE 语句)都只能引用一个基表的列。
在视图中修改的列必须直接引用表列中的基础数据。 它们不能通过其他方式派生,例如通过:
聚合函数(AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VAR 和 VARP)。
计算,不能通过表达式并使用列计算出其他列。 使用集合运算符(UNION、UNION ALL、CROSSJOIN、EXCEPT 和 INTERSECT)形成的列得出的计算结果不可更新。
被修改的列不受 GROUP BY、HAVING 或 DISTINCT 子句的影响。
同时指定了 WITH CHECK OPTION 之后,不能在视图的 select_statement 中的任何位置使用 TOP。
上述限制应用于视图的 FROM 子句中的任何子查询,就像其应用于视图本身一样。 通常,SQL Server 2008 必须能够从一个基表的视图定义明确跟踪修改。 例如,以下视图不可更新:
CREATE VIEW TotalSalesContacts
AS
SELECT C.LastName,
SUM(O.TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader O, Person.Contact C
WHERE C.ContactID = O.ContactID
GROUP BY LastName
不能接受对 TotalSalesContacts 的 LastName 列进行修改,因为该列已受到 GROUP BY 子句的影响。 如果同一个姓氏有多个实例,则 SQL Server 将无法知道该更新、插入或删除哪个实例。 同样,尝试对 TotalSalesContacts 的 TotalSales 列进行修改将返回错误,因为该列是从聚合函数派生的列。SQL Server 不能直接跟踪该列到其基表 SalesOrderHeader。
另外还将应用以下附加准则:
如果在视图定义中使用了 WITH CHECK OPTION 子句,则所有在视图上执行的数据修改语句都必须符合定义视图的 SELECT 语句中所设置的条件。 如果使用了 WITH CHECK OPTION 子句,修改行时需注意不让它们在修改完成后从视图中消失。 任何可能导致行消失的修改都会被取消,并显示错误。
INSERT 语句必须为不允许空值并且没有 DEFAULT 定义的基础表中的所有列指定值。
在基础表的列中修改的数据必须符合对这些列的约束,例如为 Null 性、约束及 DEFAULT 定义等。 例如,如果要删除一行,则相关表中的所有基础 FOREIGN KEY 约束必须仍然得到满足,删除操作才能成功。
不能使用由键集驱动的游标更新分布式分区视图(远程视图)。 此项限制可通过在基础表上而不是在视图本身上声明游标得到解决。
bcp 或 BULK INSERT 和 INSERT ... SELECT * FROM OPENROWSET(BULK...) 语句不支持将数据大容量导入到分区视图。 但是,您可以使用 INSERT 语句在分区视图中插入多行。 有关详细信息,请参阅从视图大容量导出数据或将数据大容量导入视图。
不能对视图中的 text、ntext 或 image 列使用 READTEXT 语句和 WRITETEXT 语句。
通过视图修改数据的其他选择
如果本主题的上述限制妨碍直接通过视图修改数据,则可以考虑下列选项:
使用具有支持 INSERT、UPDATE 和 DELETE 语句的逻辑的 INSTEAD OF 触发器。 有关详细信息,请参阅设计 INSTEAD OF 触发器。
使用修改一个或多个成员表的可更新分区视图。 有关详细信息,请参阅创建分区视图。
通过视图添加数据
通过视图更改数据
通过视图删除数据