2014-10-10 3 views
0

저는 사람들이 SMS 메시지를 보낼 수있는 프로그램을 작성하고 있습니다. 우리가 보낸 단어를 인식하면 작업을 수행합니다. 우리가 인식 (취급)하는 키워드는 날짜를 기준으로 변경됩니다. 예를 들어 제가 일하는 교회는 항상 부활절 자원 봉사자가 많이 필요하기 때문에 부활절 2 개월 전부터 '부활절'을 키워드로 지정하고 부활절 이후에는 사용을 중지하고 싶습니다.날짜 범위를 사용하는 SQL Server 기본 키

따라서 기본 키는 <keyword, date-range>이어야합니다. 나는 <keyword, date-start, date-end>으로 설정할 수 있지만 동일한 키워드와 날짜 - 시작 또는 날짜 - 끝으로 새 레코드를 삽입하려고하면 PK 충돌 (또는 적어도 일종의 제약 조건 충돌)이 발생합니다. 행의 날짜 - 시작 및 종료 날짜.

내 최선의 행동 강령은 무엇인가요? SQL Server에이 기능이 내장되어 있습니까? .NET에서 일종의 사용자 정의 유형을 만들어야합니까? 기본 키 또는 2 차 점검 제한 조건으로이 작업을 수행합니까?

나는 항상 속도를 위해 최적화하는 것을 좋아하지만, 사실이 앱은 실제로는 필요하지 않습니다.

+0

내장 아무것도 없다 당신이 할 필요가 만드는 것입니다. 용어 및 날짜 필터 테이블. – durbnpoisn

+0

@durbnpoisn 날짜 필터 란 무엇을 의미합니까? – dfoverdx

+0

"[dateIs] [beginDate]와 [endDate] 사이의 위치"를 포함하는 select 문을 실행합니다. 오늘 날짜로 전달합니다. 귀하의 테이블에는 해당 범위에 나타나는 키워드의 시작일과 종료일이 있습니다. – durbnpoisn

답변

2

은 당신이 함수와 쌍을 이루는 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') 

Sample SQL Fiddle

+0

이것은 기본적으로 카운트가 1인지 확인하기보다는 내가 끝낸 것입니다. keyword_id int를 포함 시켰습니다. WHERE 절에서 검사중인 행이 삽입되는 행이 아닌지 확인했습니다. – dfoverdx

2

아마도 SQL Server 수준이 아닌 응용 프로그램 수준에서이를 적용해야 할 것입니다. SQL Server는 범위를 적용 할 수 있지만 각 범위가 고정 된 표준 시작 시간 및 길이로 평가되는 경우에만 (즉, 항상 2 개월 범위가 항상 짝수 개월의 첫날에 시작됨). 임의의 시작 시간이나 길이를 원하면 응용 프로그램 논리를 사용하거나 최선을 다해 트리거를 수행해야합니다. 나는 중요한 뭔가를 누락하지 않는 한

+0

check 제약 조건으로 할 수 있습니까? '... CHECK (존재하지 않음 (키워드 1) k를 선택하십시오. k.word = 단어 AND (날짜와 시작 사이에 k.date_start와 k.date_end 또는 date_end와 k.date_start와 k.date_end)) ' – dfoverdx

+0

SQL 서버 당신은 Joel이 말했듯이 트리거를 사용해야 할 것입니다. 체크 제약 조건은 로우 레벨에만 있습니다 – jazzytomato

+0

그리고 겹치는 체크 조건이 틀리다고 btw 이전에 시작해서 끝나는 행을 삽입하면 어떻게됩니까? : //stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap – jazzytomato