2013-06-29 45 views
1

我很确定我做错了什么,因为这是我的第一个检查约束,但我不明白为什么它不起作用。我需要检查日期范围不重叠。检查约束不能正确发射

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到我的表,它允许插入。它应该会失败。

我在做什么错?

回答

0

如果更改SELECT * FROM project_sprintSELECT * 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)