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

我究竟做错了什么?

4

1 回答 1

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)
于 2013-06-30T05:32:54.573 回答