我应该如何可靠地标记SQL Server表中的最新行?

时间:2013-10-16 16:39:32

标签: sql triggers sql-server-2008-r2

此程序的现有设计是将所有更改写入带有时间戳的changelog表。为了获取项目属性的当前状态,我们JOIN到更改日志表中,并获取具有最新时间戳的行。

这是跟踪当前值的混乱方式,但我们目前无法轻易更改此更改日志设置。

我打算通过在changelog表中添加“IsMostRecent”位来稍微修改行为。这将允许我简单地拉出具有该位设置的行,而不是MAX()聚合或递归搜索。

您将采用什么策略来确保始终正确设置该位?或者您是否有一些替代方案,它不会影响日志表的当前使用?

目前我正在考虑一种触发方法,它会将所有其他行关闭,然后将其打开,以便INSERT上的最新行

3 个答案:

答案 0 :(得分:2)

之前我已经通过使用“MostRecentRecorded”表来完成此操作,该表只是最近插入的记录(Id和实体ID)触发了触发器。

为此添加一个额外的列是不对的 - 并且可以让您解决事务和阅读现有条目的问题。

在第一个版本中,这是一个简单的

案例
BEGIN TRANSACTION 
    INSERT INTO simlog (entityid, logmessage) 
           VALUES     (11, 'test'); 

    UPDATE simlogmostrecent 
    SET    lastid = @@IDENTITY 
    WHERE  simlogentityid = 11 
COMMIT 

确保MostRecent表有一个SimLog中每条记录的条目可以在查询中完成,但ISTR我们在创建SimLog引用的实体时做到了(上面是我对第一个版本的回忆 - 我没有代码可以处理。)

然而,简单版本导致多个编写器出现问题,因为这可能导致死锁或事务失败;所以它被移动到触发器中。

答案 1 :(得分:1)

编辑:在理查德哈里森回答之前开始这个答案,承诺:)

我会建议另一个表格,其结构类似于下面的结构:

VersionID  TableName   UniqueVal  LatestPrimaryKey
1          Orders      209        12548
2          Orders      210        12549
3          Orders      211        12605
4          Orders      212        10694

VersionID -- being the tables key
TableName -- just in case you want to roll out to multiple tables
UniqueVal -- is whatever groups multiple rows into a single item with history (eg Order Number or some other value)
LatestPrimaryKey -- is the identity key of the latest row you want to use.

然后你可以简单地JOIN到这个表只返回最新的行。

如果您已经有一个触发器将行插入更改日志表,则可以对其进行调整:

INSERT INTO [MyChangelogTable]
(Primary, RowUpdateTime)
VALUES (@PrimaryKey, GETDATE())

-- Add onto it:

UPDATE [LatestRowTable]
SET [LatestPrimaryKey] = @PrimaryKey
WHERE [TableName] = 'Orders'
AND [UniqueVal] = @OrderNo

或者它可以作为合并来完成捕获插入。

答案 2 :(得分:0)

我想到的一件事是创建一个视图来在幕后执行所有混乱的MAX()查询等。然后你应该能够查看视图。这种方式不需要改变你当前的设置,只需将所有混乱移动到一个地方。