2012-07-13 48 views
0

是否有可能知道底层表是否已更新?更新基础表时刷新ADO数据集

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

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

而不是定期刷新与说定时器,我想dataset一旦基础表记录更改。

谢谢。

回答

1

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

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

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

无论如何,如果数据量是非常大的,你想与优化发挥你有两种方式:

A.建立一个日志表,并使用触发器登记表中的数据变化。要求定期更改服务器(你可以在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(即插入/更新/删除)。如果你没有链接到DBMS,Firebird/Interbase有events的概念。使用触发器,您可以通知客户端数据已更改,并且您可以重新查找修改后的数据。

+1

我喜欢选项B,因为我会响应由事件表上的触发器触发的数据库事件,而不是定期检查是否发生了某些变化。感谢您的想法! – 2012-07-13 14:48:17

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权限才能访问管理视图。