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



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时不返回任何行。

这是怎么回事?

只有当基础表已经包含满足VIEWWHERE条件的数据时,

UPDATE语句才会抛出异常。否则,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';

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

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

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

最新更新