我一直認爲,如果有什麼東西可以在數據庫中受到約束,應該是。您永遠不知道哪個開發人員會禁用觸發器,或繞過應用程序代碼並直接運行插入,因此儘管觸發器和業務邏輯良好,但這並不是很好的證明。
我會做的第一件事是限制BEGIN_DATE是END_DATE前:
CREATE TABLE dbo.T
(
ID INT IDENTITY(1, 1) NOT NULL,
Event_name VARCHAR(50) NOT NULL,
begin_date DATE NOT NULL,
end_date DATE NOT NULL
);
ALTER TABLE dbo.T ADD CONSTRAINT CHK_T_ValidDates CHECK (Begin_date <= end_date);
然後(如果你不已經有一個),你可以創建一個日曆表(which are incredibly useful anyway):
CREATE TABLE dbo.Calendar
(
Date DATE NOT NULL
);
CREATE UNIQUE CLUSTERED INDEX UQ_Calendar_Date ON dbo.Calendar (Date);
GO
INSERT dbo.Calendar (Date)
SELECT TOP (7305) DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, '20000101')
FROM sys.all_objects a, sys.all_objects;
GO
最後,你可以創建一個索引視圖,以確保沒有日期在表中重複:
CREATE VIEW dbo.TCheck
WITH SCHEMABINDING
AS
SELECT c.Date
FROM dbo.T
INNER JOIN dbo.Calendar AS c
ON c.Date >= t.begin_date
AND c.Date <= t.end_date;
GO
CREATE UNIQUE CLUSTERED INDEX UQ_TCheck_ID ON dbo.TCheck (Date);
在我運行的測試中(與觸發器相比),索引視圖比觸發器執行效果好了約50%,但都表現不佳。不幸的是,有時數據完整性會帶來成本。
瞭解SQL。閱讀觸發器。寫一個停止插入。 – TomTom 2014-11-06 14:33:58
湯姆是對的,你可以使用觸發器。另外,你可以在表格上使用Check Constraint。檢查此URL檢查約束:http://msdn.microsoft.com/en-us/library/ms179491%28v=sql.105%29.aspx – 2014-11-06 14:38:57
可能值得一讀[存儲沒有重疊的時間間隔](http ://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/03/08/storing-intervals-of-time-with-no-overlaps.aspx) – GarethD 2014-11-06 17:10:09