Sql server 如何从SQL Server数据库中获取已修改记录的列表?

Sql server 如何从SQL Server数据库中获取已修改记录的列表?,sql-server,Sql Server,我目前正在改造我公司的管理系统,使其在网络流量方面更加精简。现在,我正试图找到一种有效的方法,只查询自上次询问以来(任何用户)修改过的记录 当应用程序启动时,它加载作业信息并在本地缓存,如下所示:SELECT*FROM jobs 我正在写出记录被修改的日期/时间,其中JobID=@JobID更新作业集Widgets=@Widgets,LastModified=GetDate() 当任何用户请求作业列表时,我会查询自上次请求该列表以来已修改的所有记录,如下所示:从LastModified>=@La

我目前正在改造我公司的管理系统,使其在网络流量方面更加精简。现在,我正试图找到一种有效的方法,只查询自上次询问以来(任何用户)修改过的记录

当应用程序启动时,它加载作业信息并在本地缓存,如下所示:
SELECT*FROM jobs

我正在写出记录被修改的日期/时间,其中JobID=@JobID更新作业集Widgets=@Widgets,LastModified=GetDate()

当任何用户请求作业列表时,我会查询自上次请求该列表以来已修改的所有记录,如下所示:
从LastModified>=@LastRequested
的作业中选择*并在用户再次请求时将请求的日期/时间存储为@LastRequest。理论上,这将只返回自上次请求以来已修改的记录


我遇到的问题是当用户的日期/时间与服务器的日期/时间不完全同步时,以及在查询未索引的日期/时间列时服务器负载的问题。有没有比查询日期/时间信息更有效的系统?

最简单的解决方案似乎是以一次为先导


一种方法是确定服务器时间。更新行后,在客户端存储由
select LastModified where JobID=@JobID
返回的值。这样,客户机可以只使用服务器时间作为参考有效地进行查询。

我不知道我会依赖日期时间,因为它是SQL server外部的

如果您有一个标识列,我会在表中使用该列
UserId、LastQueryDateTime、LastIdRetrieved

每次查询基表时,都要在此表中插入用户的新行(或更新最大id,如果存在)。此外,查询应该从该表中读取行以获取LastIdRetrieved,并在where子句中使用该行


如果您的所有代码都选择从SQL Server而不是从客户端计算机插入GetDate(),则可以消除所有这一切,但这项任务相当耗费人力。

使用更新序列号(USN),就像Active Directory和DNS使用一样,跟踪自上次复制以来已更改的对象。选择一个数字作为开始,每次插入或修改作业表中的记录时,写入最新的USN。跟踪上次执行Select查询时的USN,这样您就可以始终知道自上次查询以来更改了哪些记录。例如

Set LastQryUSN = 100

Update Jobs Set USN=101, ...

Update Jobs Set USN=102, ...

Insert Jobs (USN, ...) Values (103, ...)

Select * From Jobs Where USN > LastQryUSN

Set LastQryUSN = 103

Update Jobs Set USN=104

Insert Jobs (USN, ...) Values (105, ...)

Select * From Jobs Where USN > LastQryUSN

Set LastQryUSN = 105

。。。依此类推

当您获得作业时,也要获得服务器时间:

DECLARE @now DATETIME = GETUTCDATE();

SELECT @now AS [ServerTime], * FROM Jobs WHERE Modified >= @LastModified;
第一次将最短日期传递为@LastModified。在随后的每次调用中,您都会传入上次调用返回的ServerTime。这样,客户机时间就从等式中去掉了

我希望,服务器负载的答案是显而易见的:在修改的列上添加索引


还有一个忠告:永远不要使用本地时间,即使是在服务器上。始终使用UTC时间,并将UTC时间存储在修改后的时间中。就目前而言,您的程序每年有两次完全崩溃,一次是设置夏令时更改,另一次是删除夏令时更改。

当前的SQL Server具有更改跟踪功能,您可以完全使用它。只需在要跟踪的表上启用更改跟踪。

+1用于服务器端日期时间-当然这是可行的,但由于许多其他原因,这也很重要。尝试得不错,但服务器时间不一定会向前移动-它可能会“变戏法”,这可能会导致这些查询中的数据丢失。服务器定期将其时间同步到active directory,但这并不能保证不会导致向前/向后的小跳跃。