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_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)
于 2013-06-30T05:32:54.573 に答える