仅按日期缓慢更改尺寸

时间:2014-12-11 08:29:19

标签: sql sql-server scd

我有一个数据库表,使用缓慢变化的维度的数据仓库的概念来跟踪旧版本。 所以,我用Log Trigger机制实现了它。

我的表是这样的:

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

我创建了一个hystory表

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

然后,通过这样的触发器,我得到了历史记录:

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

并且,为了查询历史表,我使用

SELECT  Id, Description
    FROM T_MyTableHistory
    WHERE @DATE >= StartDate
    AND (@DATE < EndDate OR EndDate IS NULL)

现在,我的问题是:我的客户实际上会通过仅限日期查询历史记录表(即没有当天的时间),因此我需要在该日期获取记录版本。 我想到了两个选择:

  1. 更改触发器(如何?)只记录一个&#34;历史&#34;记录每个日期。

  2. 按原样保留触发器,记录数据库中的所有更改(包括日期和时间),然后查询历史记录表以获取特定日期的最新版本(如何?)

  3. 我的感觉是第二个选项更容易实现,否则触发器可能会变得复杂(INSERT或UPDATE,具体取决于当前日期的历史记录的存在)。

    我在选择正确的方向方面需要一些帮助,并且我想在所选的选项中找到所需的SQL查询示例。

2 个答案:

答案 0 :(得分:0)

我同意你的第二意见。  保存日期和时间是很好的。在根据日期使用过滤数据时 CONVERT()函数确保仅比较DATE。此外,当客户输入单个日期时,如果记录具有相同的开始和结束日期 它们不会在您的过滤器中,因此使用日期&gt; = StartDate和日期&lt; = EndDate not(&gt; =,&lt;)

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

答案 1 :(得分:0)

最后,我提出了这个问题:

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&lt; - &gt; datetime转换更快,并且它也应该是与语言环境无关的。 顺便说一句,此查询不应该需要TOP 1ORDER BY子句,因为函数

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

自动返回所选日期,使用&#34;午夜&#34;时间(例如20141215 00:00:00),因此具有相同日期的记录会自动从结果中删除。

<强>参考文献:

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

Best approach to remove time part of datetime in SQL Server