检查约束未正确触发

时间:2013-06-29 23:40:10

标签: sql-server constraints check-constraints

我很确定我做错了,因为这是我的第一个检查限制,但我无法理解为什么它不起作用。我需要检查日期范围是否重叠。

ALTER FUNCTION fn_DateOverlaps (@StartDate DATE, @EndDate DATE, @ProjectID INT)
RETURNS BIT
AS
BEGIN
    DECLARE @Ret BIT
    SET @Ret = 1

   IF NOT EXISTS(
        SELECT * FROM project_sprint
        WHERE ((@StartDate >= StartDate AND @EndDate <= EndDate)
        OR (@StartDate <= StartDate AND @EndDate >= EndDate))
        AND ProjectId = @ProjectId
        ) 
    BEGIN
        SET @Ret = 0
    END
    RETURN @Ret
END
GO

然后我将它应用到我的桌子上:

ALTER TABLE Project_Sprint WITH CHECK ADD CONSTRAINT ck_DateOverlaps CHECK (dbo.fn_DateOverlaps([StartDate], [EndDate], [ProjectId])=1)
GO

当我测试这个功能时,我得到了一个好结果:

SELECT dbo.fn_DateOverlaps('2013-06-10', '2013-06-13', 1)

但是当我将相同的日期范围和项目ID应用于我的表时,它允许插入。它应该失败。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

如果您将SELECT * FROM project_sprint更改为SELECT * FROM dbo.project_sprint该功能将正确评估,您将无法获得所需的行为,因为您插入或编辑的值将导致对不想要的发现 为防止这种情况,您必须添加一个额外的ID字段,除了您要编辑/插入的行以进行检查。

Create Table Project_Sprint(ID int IDENTITY(1,1) NOT NULL,ProjectID int,StartDate DateTime,EndDate DateTime)

go


Alter FUNCTION fn_DateOverlaps (@ID int,@StartDate DATE, @EndDate DATE, @ProjectID INT)
RETURNS BIT
AS
BEGIN
    DECLARE @Ret BIT
    SET @Ret = 0

   IF NOT EXISTS(
        SELECT * FROM dbo.project_sprint
        WHERE
        @ID<>ID AND
         ((@StartDate >= StartDate AND @EndDate <= EndDate)
        OR (@StartDate <= StartDate AND @EndDate >= EndDate))
        AND ProjectId = @ProjectId
        ) 
    BEGIN
        SET @Ret = 1
    END
    RETURN @Ret
END
GO
ALTER TABLE Project_Sprint  ADD CONSTRAINT ck_DateOverlaps CHECK (dbo.fn_DateOverlaps([ID],[StartDate], [EndDate], [ProjectId])=1)