2014-12-11 3 views
0

이전 버전을 추적하기 위해 천천히 변화하는 차원의 데이터웨어 하우징 개념을 사용하는 데이터베이스 테이블이 있습니다. 그래서 Log Trigger 메커니즘으로 구현했습니다.천천히 날짜가 변경되는 치수

내 표는 다음과 같이이다 :

CREATE TRIGGER TableTrigger ON T_MyTable FOR DELETE, INSERT, UPDATE AS 

DECLARE @NOW DATETIME 
SET @NOW = CURRENT_TIMESTAMP 

UPDATE T_MyTableHistory 
    SET EndDate = @now 
    FROM T_MyTableHistory, DELETED 
WHERE T_MyTableHistory.Id = DELETED.Id 
    AND T_MyTableHistory.EndDate IS NULL 

INSERT INTO T_MyTableHistory (Id, Description, StartDate, EndDate) 
SELECT Id, Description, @NOW, NULL 
    FROM INSERTED 

:

CREATE TABLE "T_MyTable" (
    "Id" INT NOT NULL DEFAULT NULL, 
    "Description" NVARCHAR(255) NULL DEFAULT NULL) 

나는 이런 트리거,

CREATE TABLE "T_MyTableHistory" (
    "Id" INT NOT NULL DEFAULT NULL, 
    "Description" NVARCHAR(255) NULL DEFAULT NULL, 
    StartDate DATETIME, 
    EndDate DATETIME) 

그런 다음 hystory 테이블을 생성, 나는 역사를 얻을 그리고 기록 표를 쿼리하기 위해 나는

를 사용합니다. 10
SELECT Id, Description 
    FROM T_MyTableHistory 
    WHERE @DATE >= StartDate 
    AND (@DATE < EndDate OR EndDate IS NULL) 

지금 내 질문은 다음과 같습니다. 내 고객이 실제로 (예 : 그날의 시간없이), 그래서 그 날짜에 레코드 버전을 얻을 필요가있다.

  1. 변경 날짜 당 하나의 "역사"레코드를 기록 (어떻게?) 트리거 : 나는 약 2 옵션을 생각했다.

  2. (날짜 및 시간 포함) 데이터베이스의 모든 변경 사항을 기록,있는 그대로 방아쇠를 유지하지만 특정 날짜의 최신 버전을 얻을 수있는 역사 테이블을 쿼리 (어떻게?)

제 생각에는 두 번째 옵션을 구현하는 것이 더 쉽다는 것입니다. 그렇지 않으면 트리거가 복잡해질 수 있습니다 (현재 날짜에 대한 기록 레코드의 존재 여부에 따라 INSERT 또는 UPDATE).

올바른 방향을 선택하는 데 도움이 필요하며 선택한 옵션에 필요한 SQL 쿼리의 예가 필요합니다.

답변

0

, 나는이 쿼리를 내놓았다. 그런데 ,이 쿼리는 기록 그래서

DateAdd(day, datediff(day,0, @MyDate) 

가 자동으로 "자정"시간, 선택한 날짜를 반환하는 기능 (예 : 20141215 0시 0분 0초) 때문에, TOP 1ORDER BY 절을 필요가 없습니다 동일한 날짜의 결과는 자동으로 결과에서 제외됩니다.

참고 :

How to return the date part only from a SQL Server datetime datatype

Best approach to remove time part of datetime in SQL Server

0

나는 두 번째 의견에 동의합니다. 시간과 함께 날짜를 저장하는 것이 좋습니다. 날짜를 기반으로 데이터를 필터링하는 동안 DATE 만 비교되었는지 확인하려면 함수 CONVERT()을 사용하십시오. 기록이 같은 시작과 끝 날짜 가 필터에있을 그래서 사용 날짜> = STARTDATE 및 날짜 < = 종료 날짜하지 않습니다이있는 경우 또한, 때 클라이언트는 하나의 날짜를 입력합니다 (> =, <)

DECLARE @Date AS DATETIME 
SET @Date = '2013-07-30' 

SELECT TOP 1 Id, Description 
    FROM T_MyTableHistory 
    WHERE CONVERT(VARCHAR(20), @DATE, 103) 
     >= CONVERT(VARCHAR(20), StartDate, 103) 
    AND (CONVERT(VARCHAR(20), @DATE, 103) 
     < CONVERT(VARCHAR(20), EndDate, 103) OR EndDate IS NULL) 
    ORDER BY StartDate DESC 

SELECT Id, Description 
    FROM T_MyTableHistory 
    WHERE (DateAdd(day, datediff(day,0, @MyDate), 0) >= StartDate) AND 
    ((DateAdd(day, datediff(day,0, @MyDate), 0) < EndDate) OR (EndDate IS NULL)) 

이것은 VARCHAR <보다 더 빨리해야한다 -> 날짜 변환, 또한 로케일에 의존해야합니다 : 끝에

+0

는 답변 주셔서 감사합니다. 사실, 같은 날 (다른 시간)에 여러 버전이있는 경우 쿼리를 사용하면 동일한 ID로 많은 레코드를받을 수 있습니다. 맞습니까? 내가 원하는 것은 지정된 날짜에 유효한 최신 레코드입니다. – Nova

+0

간단합니다. 첫 번째 레코드에는 TOP 1을 사용하고 데이터 정렬에는 ORDER BY StartDate DESC를 사용하십시오. 내 대답을 업데이트 해보십시오. – Veera