更新基础表时刷新ADO数据集

时间:2012-07-13 09:09:37

标签: delphi dataset ado

是否可以让ADO Dataset'知道'基础表是否或何时更新?

目前,每当我收到文件夹中该项目的文件时,我都必须检查项目状态。这导致了很多sql查询,因为我们一次最多可以获得1300个事件。

我正在考虑向保存状态的应用程序添加ADO Dataset,并使用Locate来检查状态。

我不想定时更新计时器,而是希望在更改基础表记录后立即更新dataset

感谢。

2 个答案:

答案 0 :(得分:1)

ADO数据集根据客户端/服务器概念将数据检索到客户端。像网络浏览器一样。

这意味着:客户请求 - >服务器,服务器答案 - >客户。所以客户真的不知道是否有任何数据被更改。

最简单的方法是根据您的需要重新查询数据(关闭/打开)并获取数据,而不是一次全部1300。这是最常用的解决方案。

无论如何,如果数据量确实很大并且你想要进行优化你有两种方法:

一个。使用触发器构建日志表并注册表数据更改。定期询问服务器是否有更改(您可以在background thread中执行此操作):

select L.RECORD_ID, L.OPERATION_ID
from FILE_LOG L
where L.FDATESTAMP between :LAST_WATCH and :CURRENT_STAMP and L.FOLDER_ID = :FOLDER_ID

您将获得RECORD_ID和OPERATION_ID(即插入/更新/删除)。

B中。如果您未链接到DBMS,Firebird / Interbase具有events概念。使用触发器,您可以通知客户端数据已更改,您可以重新查询已修改的数据。

答案 1 :(得分:0)

据我们所知,SQL Server中只有一种方法可以检测是否对表进行了任何更改,即使用动态管理视图sys.dm_db_index_usage_stats(http://msdn.microsoft.com/en-us/library/ms188755.aspx)。

出于我的目的,我创建了一个功能,使访问信息更容易。

create function [dbo].[_efnLastTableUpdateTime](@TableName varchar(255))
/*  Function to return the last datetime that a table was modified.
    Note that because this is from a dynamic management view, it is only
    since the server was started, i.e. will return null if no change since
    the server was started.
    SQL2005 or later.
*/
returns datetime
as
begin
    declare @Result datetime
    set @Result = (
            select top 1 [last_user_update]
            from sys.dm_db_index_usage_stats
            where object_id=object_id(@TableName)
            order by [last_user_update] desc
        )
    return @Result
end
GO

然后我在TADOQuery的后代中构建了一个访问它的函数和一个用于打开或关闭功能的属性。然后,我可以根据需要调用它,从而产生非常有效的响应。

function TMyADOQuery.HasBeenUpdatedSinceOpen(const ACloseIfHasBeen: boolean = false): boolean;
const
  sSelectTableUpdateTime = 'select [dbo]._efnLastTableUpdateTime(''%s'')';
var
  NewUpdateTime: TDateTime;
begin
  Result := false;
  if(_TrackUpdated) and (Active) and (_TableName > '') then begin
    NewUpdateTime := TrackUpdateQuery.SelectScalarDate(Format(sSelectTableUpdateTime, [_TableName]), 0);
    Result := (FLastUpdateTime <> NewUpdateTime);
    FLastUpdateTime := NewUpdateTime;
  end;
  if(Result) and (ACloseIfHasBeen) then
    Close;
end;

TrackUpdateQuery是内部创建的TADOQuery的另一个实例,SelectScalarDate是我的TADOQuery类的扩展。

请注意,用户必须获得VIEW SERVER STATE权限才能访问管理视图。