9

我有一个有 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

if col3 is NOT NULL then col1 AND col2 must be NULL

col3应该是null如果col1并且col2不为空,反之亦然

我对 SQL 和 SQL Server 很陌生,但不确定如何实际实现它,或者即使它可以/应该实现?

我想也许:

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

但是我不确定括号是否可以用来对这样的逻辑进行分组?如果没有,如何最好地实施?

4

3 回答 3

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))

取决于你的意图。

于 2013-08-09T12:17:44.893 回答
4

请注意不要用括号弄错。

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
于 2013-08-09T12:27:10.320 回答
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))
于 2013-08-09T12:34:49.287 回答