我有一个数据库表,使用缓慢变化的维度的数据仓库的概念来跟踪旧版本。 所以,我用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)
现在,我的问题是:我的客户实际上会通过仅限日期查询历史记录表(即没有当天的时间),因此我需要在该日期获取记录版本。 我想到了两个选择:
更改触发器(如何?)只记录一个&#34;历史&#34;记录每个日期。
按原样保留触发器,记录数据库中的所有更改(包括日期和时间),然后查询历史记录表以获取特定日期的最新版本(如何?)
我的感觉是第二个选项更容易实现,否则触发器可能会变得复杂(INSERT或UPDATE,具体取决于当前日期的历史记录的存在)。
我在选择正确的方向方面需要一些帮助,并且我想在所选的选项中找到所需的SQL查询示例。
答案 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 1
和ORDER 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