我有兩個數據庫,我需要確保一個數據庫中的所有記錄在另一個數據庫中有匹配的記錄。我將這些稱爲DB-SQL和DB-LegacyClientDataSet只部分從TADOQuery傳輸數據
如果兩者都有SQL接口,這很容易,但不幸的是我只有這種類型的訪問權限,另一個我有'find record/first /下一個'類型的界面。
我所選擇來執行此任務的方法是將DB-SQL通過下面的代碼傳送到ClientDataSet的:在http://www.podgoretsky.com/ftp/docs/Delphi/D5/dg/5_ds3.html#20536
var
lQuery: TADOQuery;
lProvider: TDataSetProvider;
lDataSet: TClientDataSet;
begin
lQuery := TADOQuery.Create(nil);
lProvider := TDataSetProvider.Create(nil);
lDataSet := TClientDataSet.Create(nil);
// we don't need either of these and should speed things up
lDataSet.disablecontrols;
lQuery.DisableControls;
try
lQuery.Connection := aConnection;
lQuery.SQL.Add('SELECT FieldA, FieldB, FieldC, 0 as FoundInGIS');
lQuery.SQL.Add('FROM TableA');
// following two lines needed to allow us to modify the FoundInGIS field in the clientdataset
lQuery.open;
lquery.fieldbyname('FoundInGIS').Readonly := false;
lProvider.DataSet := lQuery;
lDataSet.Data := lProvider.Data;
lDataSet.fieldbyname('FoundInGIS').readonly := false;
lDataSet.LogChanges := false;
// index by FieldA for quick searching by FindKey later
lDataSet.IndexFieldNames := 'FieldA';
finally
lQuery.Free;
lProvider.Free;
end;
這是基於代碼然後這將允許我使用First/Next迭代DB-legacy直到EOF,使用FindKey搜索ClientDataSet以確保DB-Legacy中的所有記錄存在於DB-SQL中。通過將FoundInGIS標記設置爲1,我可以通過此值進行過濾,以查找DB-SQL中但不在DB-Legacy中的所有記錄。
我的問題是我們的一個數據庫比其他數據庫大得多,總數爲3,310,510條記錄。 lQuery具有正確的記錄數,但是在過程結束時,lDataSet只有大約2,500,000個記錄。
現在,我想使用CD來使用FindKey方法,這在TADOQuery中不受支持,但是如果它忽略1/3記錄,它沒有多大用處!我猜測DataSetProvider或ClientDataSet中的某處可能會出現整數溢出,儘管它有點頑皮,它不會引發異常!有沒有其他人有這種問題,有沒有一種方法來排序它(也許通過以較小的塊下載數據或使用另一種填充CDS的方式)?
本例中的SQL-DB是Oracle,但代碼也需要與SQL-Server一起工作,但我懷疑這是數據庫問題。
編輯: 現在我得到一些稍微不同的行爲。當我嘗試從查詢中刪除一些字段時,它運行良好。所有的字段單獨運行,但它不能處理所有的字段(這支持我的溢出假設)。我現在,但偶爾會有例外。唯一的例外是
'Format '%s' invalid or incompatible with argument'
這是誤導,因爲鑽研向下調試的DCU表示正在由
SafeArrayCheck(SafeArrayCopy(VarToDataPacket(Value), FSavedPacket));
在TCustomClientDataSet.SetData
(與dbclient線1482)引發的錯誤。這引發了ESafeArrayError(AResult = -2147024882),它變成了「意外的變體或安全數組錯誤」,但它無法處理對FormatStr的後續調用。
我的問題是我們的一個數據庫比其他數據庫大得多,在3,310,510條記錄上。 lQuery具有正確的記錄數,但是在過程結束時,lDataSet只有大約2,500,000個記錄。 - 原始數據集中是否存在沒有插入新數據集的重複記錄? –
如果有的話肯定不應該被放入原始的lQuery中?無論如何,我認爲我現在已經修好了。 –