0

是否有可能ADO Dataset“知道”基础表是否已更新或何时更新?

目前,每次在文件夹中收到该项目的文件时,我都必须检查项目状态。这会导致大量的 sql 查询,因为我们一次最多可以处理 1300 个事件。

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

我不想使用计时器进行定期刷新,而是希望dataset在基础表记录更改后立即更新。

谢谢。

4

2 回答 2

1

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

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

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

无论如何,如果数据量真的很大并且你想玩优化你有两种方法:

A. 使用触发器构建日志表并注册表数据更改。定期向服务器询问更改(您可以在后台线程中执行此操作):

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 有事件的概念。使用触发器,您可以通知客户端数据已更改,并且您可以重新查询刚刚修改的数据。

于 2012-07-13T11:57:20.607 回答
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权限才能访问管理视图。

于 2012-07-13T11:56:36.763 回答