CHECK约束可以像其他一样吗?

时间:2013-08-09 12:11:54

标签: sql sql-server check-constraints

我有一个包含4列的表(ID(PK,int,NOT NULL),col1(NULL),col2(NULL),col3(NULL))

我想添加一个CHECK约束(我认为表级别?),以便:

if col1 OR col2 are NOT NULL then col3 must be NULL

和     如果col3为NOT NULL,则col1 AND col2必须为NULL

即。如果col1和col2不为null,则col3应为null,反之亦然

我是SQL和SQL服务器的新手,但我不确定如何实际实现它,即使它可以/应该实现?

我想也许:

CHECK ( (col1 NOT NULL OR col2 NOT NULL AND col3 NULL) OR 
        (col3 NOT NULL AND col1 NULL AND col2 NULL) )

但我不确定是否可以使用括号将这样的逻辑分组?

如果没有,最好如何实施?

3 个答案:

答案 0 :(得分:11)

当然,你可以做到这一点。请参阅此sqlfiddle

但是,您需要确保正确组合逻辑。您应该从不在同一包围范围内混合AND和OR。所以:

(col1 NOT NULL OR col2 NOT NULL AND col3 NULL)

需要成为:

((col1 NOT NULL OR col2 NOT NULL) AND col3 NULL)

或者:

(col1 NOT NULL OR (col2 NOT NULL AND col3 NULL))

取决于您的意图。

答案 1 :(得分:3)

小心不要用括号弄错。

CREATE TABLE Test1 (col1 INT, col2 INT, col3 INT);


ALTER TABLE Test1 
ADD CONSTRAINT CHK1
CHECK  (((col1 IS NOT NULL OR col2 IS NOT NULL) AND col3 IS NULL) OR 
        ((col1 IS NULL AND col2 IS NULL) AND col3 IS NOT NULL))



INSERT INTO Test1 VALUES (1,1,1); --fail
INSERT INTO Test1 VALUES (1,1,NULL); --good
INSERT INTO Test1 VALUES (1,NULL,NULL); --good
INSERT INTO Test1 VALUES (1,NULL,1); --fail
INSERT INTO Test1 VALUES (NULL,NULL,1); --good

答案 2 :(得分:1)

我想说创建一个如下所示的UDF

create FUNCTION dbo.fn_check_val
  (@col1 int , @col2 int , @col3 int)
RETURNS bit
AS
BEGIN
    declare @toRet bit
    IF(@col1 is Not null OR @col2 is NOT NULL)
    Begin
        if(@col3 is null)
        Begin
            Set @toRet = 1
        End
        Else
        Begin
            Set @toRet = 0
        End
    End
    Else
    if(@col3 is not null)
    Begin
        Set @toRet = 1
    End
    Else
    Begin
        Set @toRet = 0
    End
return @toRet
END

然后在表中添加以下检查语句

([dbo].[fn_check_val]([col1],[col2],[col3])=(1))