我很确定我做错了,因为这是我的第一个检查限制,但我无法理解为什么它不起作用。我需要检查日期范围是否重叠。
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 :(得分: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)