2013-02-03 20 views
6

Czy mogę pisać zapytania SQL przy użyciu DELPHI, komponentów dbgo DB i serwera bazy danych SQL Server, które są ograniczone pod względem czasu przetwarzania?Przerwij zapytanie SQL z limitem czasu przetwarzania

Jak

select * from table where ...... 

i process_time_limit = 5 sec?

Lepiej dać mi 10% wierszy w terminie, a nie godzin czekając na kompletnego zestawu danych kwerendy

+0

Co chcesz zdarzyć, gdy została osiągnięta 5 sekund? Wyjątek, który możesz obsłużyć lub coś innego? I jakiej wersji używasz (może Resource Governor może pomóc tutaj). –

+0

Zobacz także http://stackoverflow.com/questions/5077051/ado-components-commandtimeout - "CommandTimeout" może pomóc, ale może zależeć od kilku innych czynników. –

+3

Może powinieneś unikać rozpoczynania zapytań, których wypełnienie zajmuje wiele godzin. –

Odpowiedz

3

ADO składniki:

chciałbym spróbować do danych asynchroniczny sprowadzać. Po uruchomieniu zapytania zapamiętasz, kiedy uruchomisz i za każdym razem, gdy zostanie wywołane zdarzenie OnFetchProgress, sprawdzisz, czy EventStatus nadal znajduje się w stanie i sprawdza czas, jaki upłynął od wykonania zapytania. Jeśli upłynął, możesz anulować pobieranie danych przy użyciu metody Cancel w swoim zestawie danych.

chciałem użyć coś jak poniżej (untested) Pseudokod:

var 
    FQueryStart: DWORD; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    // configure the asynchronous data fetch for dataset 
    ADOQuery1.ExecuteOptions := [eoAsyncExecute, eoAsyncFetchNonBlocking]; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    // store the query execution starting time and execute a query 
    FQueryStart := GetTickCount; 
    ADOQuery1.SQL.Text := 'SELECT * FROM Table'; 
    ADOQuery1.Open; 
end; 

procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress, 
    MaxProgress: Integer; var EventStatus: TEventStatus); 
begin 
    // if the fetch progress is in esOK (adStatusOK) status and the time since 
    // the query has been executed (5000 ms) elapsed, cancel the query 
    if (EventStatus = esOK) and (GetTickCount - FQueryStart >= 5000) then 
    DataSet.Cancel; 
end; 
+0

Hmm, dokument dla "Anuluj" mówi: "Anuluje modyfikacje aktywnego rekordu, jeśli te zmiany nie zostały jeszcze opublikowane." Jesteś pewien, że to zadziała w zamierzonym celu tutaj - aby anulować następne pobranie? – ain

+1

Dzięki temu dzieleniu się pomysłami, będę miał atry na tym – Franz