2012-07-13 50 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權限才能訪問管理視圖。