使用CHECK OPTION更新视图会意外成功

时间:2013-09-01 06:43:44

标签: sql-server tsql

CHECK OPTION如何处理视图?尝试更新视图时,它会成功。

CREATE TABLE [dbo].[Test](
    [Country] [nvarchar](20) NULL
) ON [PRIMARY]

INSERT [Test] VALUES ('England'), ('USA'), ('Australia');

CREATE VIEW dbo.TestView AS   
SELECT Country FROM  dbo.Test 
WHERE Country = N'USA'
WITH CHECK OPTION;

我尝试通过视图插入新行,按预期失败,因为WITH CHECK OPTION带有预期的错误消息The attempted insert or update failed because the target view either specifies WITH CHECK OPTION

INSERT INTO dbo.TestView (Country) VALUES (N'Canada');

但是,此更新意外成功:

UPDATE dbo.TestView  SET Country = N'ddsffd';

执行SELECT * FROM dbo.TestView时没有返回任何行。

这里发生了什么?

2 个答案:

答案 0 :(得分:3)

仅当基础表已包含UPDATE中满足WHERE条件的数据时,

VIEW语句才会抛出异常。否则,UPDATE语句不会违反CHECK条件,因为VIEW中没有可修改的数据。

检查:

CREATE TABLE [dbo].[Test](
    [Country] [nvarchar](20) NULL
) ON [PRIMARY];


CREATE VIEW dbo.TestView AS 
SELECT Country FROM
dbo.Test WHERE Country = N'USA'
WITH CHECK OPTION;
GO

INSERT INTO dbo.[Test] (Country) VALUES (N'USA');

UPDATE dbo.TestView 
SET Country = N'ddsffd';

答案 1 :(得分:0)

您的案例在MSSQL2008中适用于我(INSERT和UPDATE都被拒绝)。

请注意,如果视图的基表具有INSERT和/或UPDATE的INSTEAD OF触发器,则视图上的任何相应操作都将静默忽略 WITH CHECK OPTION(基于触发器可以转换提供的值,因此视图无法知道实际插入/更新的行是否会违反视图的过滤器。

如果您遇到这种情况,您将被迫在视图上为INSERT和UPDATE编写INSTEAD OF触发器并自行检查过滤器。这确实意味着视图上的INSERT不会考虑基表中的DEFAULT子句,因此您必须将ISNULL应用于INSERTED中的值才能将它们正确地插入基表中。