使用日期范围的SQL Server主键

时间:2014-10-10 16:07:12

标签: sql-server

我正在编写一个允许人们发送短信的应用,如果我们识别出他们发送的字,我们会做点什么。我们识别(处理)的关键字根据日期而变化。例如,我工作的教会总是需要很多复活节志愿者,所以在复活节前的两个月,我们想要指定复活节'作为关键词,在复活节之后,我们想要禁用它。

因此主键必须是<keyword, date-range>。我可以将其设置为<keyword, date-start, date-end>,但如果我尝试插入具有相同关键字和日期开始或日期的新记录,我希望存在PK冲突(或至少某种约束冲突) - 在另一行的日期开始日期和日期结束之间。

我最好的行动方式是什么? SQL Server是否内置了此功能?我是否需要使用.NET创建某种自定义类型?我是使用主键还是辅助检查约束来执行此操作?

我总是喜欢优化速度,但事实上,这个应用并不是真的需要它。

2 个答案:

答案 0 :(得分:3)

除非我遗漏了一些重要内容,否则我相信你可以使用与check约束配对的-- test table CREATE TABLE keyword_ranges (Keyword varchar(10), Startdate date, Enddate date); -- function that checks if ranges overlap CREATE FUNCTION CheckKeywordRange (@Keyword VARCHAR(10), @Startdate date, @Enddate date) RETURNS int AS BEGIN DECLARE @retval int SELECT @retval = COUNT(*) FROM keyword_ranges WHERE keyword = @Keyword AND (@Startdate <= Enddate) and (@Enddate >= Startdate) RETURN @retval END; GO -- constraint that calls the function ALTER TABLE keyword_ranges ADD CONSTRAINT chkKeywordRange CHECK (dbo.CheckKeywordRange(Keyword, Startdate, Enddate) = 1); -- this insert will succeed INSERT keyword_ranges VALUES ('Holiday', '2014-01-01', '2014-01-05') -- this insert will conflict with the check and fail INSERT keyword_ranges VALUES ('Holiday', '2014-01-03', '2014-01-07') 约束来完成此任务:

{{1}}

Sample SQL Fiddle

答案 1 :(得分:2)

您可能需要在应用程序级别而不是Sql Server级别强制执行此操作。 Sql Server可以强制执行范围,但仅当每个范围评估为固定的规范开始时间和长度时:(即:始终具有始终在偶数月的第一天开始的2个月范围)。如果你想要任意的开始时间或长度,你就会坚持使用应用程序逻辑,或者最好只是在触发器中。