是否有可能知道底层表是否已更新?更新基础表时刷新ADO数据集
此刻,我必须在每次收到文件夹中该项目的文件时检查项目状态。这导致了很多SQL查询,因为我们一次最多可以获得1300个事件。
我正在考虑将ADO Dataset
添加到保存状态的应用程序中,并使用Locate
来检查状态。
而不是定期刷新与说定时器,我想dataset
一旦基础表记录更改。
谢谢。
是否有可能知道底层表是否已更新?更新基础表时刷新ADO数据集
此刻,我必须在每次收到文件夹中该项目的文件时检查项目状态。这导致了很多SQL查询,因为我们一次最多可以获得1300个事件。
我正在考虑将ADO Dataset
添加到保存状态的应用程序中,并使用Locate
来检查状态。
而不是定期刷新与说定时器,我想dataset
一旦基础表记录更改。
谢谢。
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的概念。使用触发器,您可以通知客户端数据已更改,并且您可以重新查找修改后的数据。
就我们所知,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权限才能访问管理视图。
我喜欢选项B,因为我会响应由事件表上的触发器触发的数据库事件,而不是定期检查是否发生了某些变化。感谢您的想法! – 2012-07-13 14:48:17