sql-server – 为什么我的检查约束不能停止这个空插入?
任何人都可以解释SQL Server允许下列代码中的第三个插入(标记为Query Data)的原因?
据我所知,支票约束应该只允许: >代码为空,系统为空. 我的第一个想法是ANSI NULLS,但是将它们设置为关闭也没有任何区别. 这是我们在应用程序中发现的更大问题的简化示例(系统已针对数字列表(IN,1,2等)进行了检查).我们用一个外键(而不是IN)替换了这个检查和一个新的检查约束,允许null或null都为null;这样做阻止了第三个插入. IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[CK_TestCheck]') AND parent_object_id = OBJECT_ID(N'[dbo].[TestCheck]')) ALTER TABLE [dbo].[TestCheck] DROP CONSTRAINT [CK_TestCheck] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestCheck]') AND type in (N'U')) DROP TABLE [dbo].[TestCheck] GO SET ANSI_NULLS ON GO CREATE TABLE TestCheck( [Id] [int] IDENTITY(1,1) NOT NULL,[Code] [varchar](50) NULL,[System] [tinyint] NULL,PRIMARY KEY CLUSTERED ([Id] ASC)) GO ALTER TABLE [dbo].[TestCheck] WITH CHECK ADD CONSTRAINT [CK_TestCheck] CHECK ( ([Code] IS NULL AND [System] IS NULL) --Both null OR ([Code] IS NOT NULL AND [System] = 1) --Both not null ???? ) GO ALTER TABLE [dbo].[TestCheck] CHECK CONSTRAINT [CK_TestCheck] GO --Good Data insert TestCheck (Code,[System]) Values(null,null); insert TestCheck (Code,[System]) Values('123',1); --Query Data insert TestCheck (Code,null); --Bad data stopped insert TestCheck (Code,1); insert TestCheck (Code,4); select * from TestCheck Where case when ( ([Code] IS NULL AND [System] IS NULL) --Both null OR ([Code] IS NOT NULL AND [System] in (1,2,3)) --Both not null ???? ) then 0 else 1 end = 1 解决方法评估值123的当前约束的结果为NULL是未定义的.>([Code] IS NULL AND [System] IS NULL)评估为False 结果未定义 Check Constraint
您应该将[系统] IN(1,3)的检查更改为ISNULL([系统],0)IN(1,3). 你的检查约束就变成了 ALTER TABLE [dbo].[TestCheck] WITH CHECK ADD CONSTRAINT [CK_TestCheck] CHECK ( ([Code] IS NULL AND [System] IS NULL) --Both null OR ([Code] IS NOT NULL AND ISNULL([System],0) IN (1,3)) --Both not null ???? ) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |