![]() ![]() ![]() ![]() ![]() ![]() ![]() |
||
BDE API Examples (DbiReadBlock, DbiWriteBlock, DbiSetFieldMap)(DbiReadBlock)Reads a specified number of records (starting from the next position of the cursor) into a buffer.(DbiSetFieldMap)Sets a field map of the table associated with the given cursor. (DbiWriteBlock)Writes a block of records to the table associated with the cursor. Move data from one table to another table with a different structure in the fastest way possible.This example uses the following input:MoveFast(STable, DTable, [2, 3, 5], [4, 1, 7], 1024000); NOTE: This procedure will take two tables of the same type and move data between the two even if they have a different structure. The above input example maps source table fields 2, 3 and 5 to 4, 1 and 7 respectively. The matching fields must be of same type and size because no field level translation is being done. Changing the BlockSize parameter can have an effect of speed. If you are moving massive amounts of data and have plenty of RAM in the machine, experiment with increasing the BlockSize parameter. procedure MoveFast(SourceTable, DestTable: TTable; const SourceMap,
DestMap: array of word; BlockSize: longint);
var
pRecBuffs: pBYTE;
TotalSize, Records, RecordsToRead, RecordsProcessed: longint;
pSMapFields, pSFields, pDMapFields, pDFields, pD, pS: pFLDDesc;
MapFieldCount, B: byte;
Props: CURProps;
begin
if sizeof(SourceMap) <> sizeof(DestMap) then
raise EDatabaseError.Create('Source and destination field mappings must be same in size');
pRecBuffs := nil; pSFields := nil; pSMapFields := nil;
pDFields := nil; pDMapFields := nil; RecordsProcessed := 0;
try
Check(DbiSetToBegin(SourceTable.Handle));
MapFieldCount := sizeof(SourceMap) div sizeof(WORD);
pSMapFields := AllocMem(MapFieldCount * sizeof(FLDDesc));
pSFields := AllocMem(SourceTable.FieldCount * sizeof(FLDDesc));
Check(DbiGetFieldDescs(SourceTable.Handle, pSFields));
// Create the source field mappings...
for B := 0 to MapFieldCount - 1 do
begin
Inc(pSFields, SourceMap[B] - 1);
Move(pSFields^, pSMapFields^, sizeof(FLDDesc));
Inc(pSMapFields);
Dec(pSFields, SourceMap[B] - 1);
end;
Dec(pSMapFields, MapFieldCount);
pDMapFields := AllocMem(MapFieldCount * sizeof(FLDDesc));
pDFields := AllocMem(DestTable.FieldCount * sizeof(FLDDesc));
Check(DbiGetFieldDescs(DestTable.Handle, pDFields));
// Create the destination field mappings...
for B := 0 to MapFieldCount - 1 do
begin
Inc(pDFields, DestMap[B] - 1);
Move(pDFields^, pDMapFields^, sizeof(FLDDesc));
Inc(pDMapFields);
Dec(pDFields, DestMap[B] - 1);
end;
Dec(pDMapFields, MapFieldCount);
// Check all fields to make sure they are comparable types and sizes...
pS := pSMapFields;
pD := pDMapFields;
for B := 1 to MapFieldCount do
begin
if pS^.iFldType <> pD^.iFldType then
raise EDatabaseError.Create('Source field: ' + pS^.szName + ' Type (' +
IntToStr(pS^.iFldType) + ') is not the same base type as the ' +
'destination field: ' + pD^.szName + ' Type (' +
IntToStr(pD^.iFldType) + ')');
if (pS^.iUnits1 <> pD^.iUnits1) or (pS^.iUnits1 <> pD^.iUnits1) then
raise EDatabaseError.Create('Source field size: ' + pS^.szName + ' Size (' +
IntToStr(pS^.iUnits1) + ', ' + IntToStr(pS^.iUnits1) +
') is not the same base type as the destination size: ' + pD^.szName + ' Size (' +
IntToStr(pD^.iUnits1) + ', ' + IntToStr(pD^.iUnits1) + ')');
Inc(pS);
Inc(pD);
end;
// Set the field maps on the tables...
Check(DbiSetFieldMap(SourceTable.Handle, MapFieldCount, pSMapFields));
Check(DbiSetFieldMap(DestTable.Handle, MapFieldCount, pDMapFields));
Check(DbiGetCursorProps(DestTable.Handle, Props));
// Determine the amount of records that can be move in the block size given...
Check(DbiGetRecordCount(SourceTable.Handle, Records));
TotalSize := Props.iRecBufSize * Records;
if TotalSize < BlockSize then
BlockSize := TotalSize;
RecordsToRead := BlockSize div Props.iRecBufSize;
pRecBuffs := AllocMem(BlockSize * sizeof(BYTE));
// Read and write the data...
while RecordsToRead > 0 do
begin
Check(DbiReadBlock(SourceTable.Handle, RecordsToRead, pRecBuffs));
Check(DbiWriteBlock(DestTable.Handle, RecordsToRead, pRecBuffs));
Inc(RecordsProcessed, RecordsToRead);
if RecordsToRead > (Records - RecordsProcessed) then
RecordsToRead := (Records - RecordsProcessed);
end;
finally
if pRecBuffs <> nil then
FreeMem(pRecBuffs);
if pSFields <> nil then
FreeMem(pSFields);
if pSMapFields <> nil then
FreeMem(pSMapFields);
if pDFields <> nil then
FreeMem(pDFields);
if pDMapFields <> nil then
FreeMem(pDMapFields);
Check(DbiSetFieldMap(SourceTable.Handle, 0, pSFields));
Check(DbiSetFieldMap(DestTable.Handle, 0, pDFields));
end;
end;
| ||
|
DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains. |
||
| Trademarks & Copyright © 1998 Borland International, Inc. | ||