2017-04-18 49 views
2

我對觸發器非常陌生,我似乎無法將我的頭圍繞在他們身上。假設我這裏有兩個表:創建在SQL Server中比較日期的觸發器

CREATE TABLE Project 
(
    id INT NOT NULL IDENTITY(1, 1), 
    startDate DATETIME, 
    endDate DATETIME 
); 

CREATE TABLE Work 
(
    date DATETIME, 
    projectId INT 
); 

我插入一些數據:

INSERT INTO Project VALUES ('2017-04-18', '2017-05-01'); /*id = 1*/ 
INSERT INTO Work VALUES ('2017-04-17', 1); 

假設這裏只有1 id = 1項目,這應該順利。然而,我的工作在項目開始的前一天開始(在這種情況下並非如此)沒有多大意義。我將如何創建基本上說date cannot be < startDate OR > endDate的觸發器?

+1

你應該在應用層處理業務規則,而不是在數據庫層。 –

+0

@WEI_DBA我知道。這完全不相關,我絕不會在真正的應用程序中這樣做。 – MortenMoulder

+0

然後...在'Work'表上使用'而不是Insert Trigger'。 –

回答

2

像這樣的東西應該工作:

CREATE TRIGGER t_CheckInterval ON dbo.Work 
    AFTER UPDATE, INSERT 
AS 

IF NOT EXISTS (
    --if no records are returned then work date lies outside the project 
    -- (start, end) interval 
    SELECT 1 
    FROM inserted AS i 
    JOIN Project AS p 
     ON p.Id = i.projectId AND i.[date] BETWEEN p.startDate AND p.endDate 
) 
BEGIN 
    RAISERROR ('Error: Your error message here.', 16, 1) 
    ROLLBACK TRANSACTION 
END 

GO 
+0

完美的作品!非常感謝。現在有更多的意義。我完全錯過了JOIN部分。 – MortenMoulder

1

在你的情況,而不是使用觸發器這幾樣checkings的,我建議使用檢查約束,這樣的事情:

CREATE FUNCTION dbo.ufn_CheckWorkDate 
(
    @WorkDate DateTime, 
    @ProjectID INT 
) 
RETURNS BIT 
AS 
BEGIN 
    DECLARE @Result BIT 

    IF EXISTS (SELECT * FROM Project WHERE id = @ProjectID AND @WorkDate BETWEEN startdate AND endDate) 
     SET @Result = 1 
    ELSE 
     SET @Result = 0 

    RETURN @Result 
END 

GO 

ALTER TABLE Work 
    WITH CHECK ADD CONSTRAINT CK_CheckWorkDate 
    CHECK (dbo.ufn_CheckWorkDate(date, projectid) = 1) 
+0

是的,使用觸發器以外的其他東西(比如CONSTRAINT)絕對好得多。謝謝。 – MortenMoulder