临时数据库建立以及将其内容复制到另一永久性数据库中。(100分)

X

xgswxgw

Unregistered / Unconfirmed
GUEST, unregistred user!
在编程过程中,需要动态建立一临时数据库,并且需要把其中的内容转移到另一永久性的数据库中,请教哪位高手,怎样解决?
 
可使用TQuery构件,指定好DatabaseName在SQL内使用下列语句:
CREATE TABLE <表名> ( <表结构> )
调用TQuery的ExecSQL方法后即可建立此数据表。删除时使用下列语句:
DROP TABLE <表名>
同样调用ExecSQL。

例如:
with Query1 do
begin
DatabaseName:='DBDEMOS';
SQL.Clear;
SQL.Add('CREATE TABLE TEMP(FA CHAR(10) ,FB NUMBER DEFAULT 0)');
ExecSQL;
end;
数据表TEMP处理数据后需转入数据表MYDATA中;
with Query1 do
begin
DatabaseName:='DBDEMOS';
SQL.Clear;
SQL.Add('INSERT INTO MYDATA SELECT * FROM TEMP');
ExecSQL;
SQL.Clear;
SQL.Add('DROP TABLE TEMP');
ExecSQL;
end;

 
下面是一个 InMemeryTable 的类,除了不支持 Blob 字段和 Secondary Index外,
可以如普通 Table一样操作。

unit Inmem;

interface

uses DBTables, WinTypes, WinProcs, DBITypes, DBIProcs, DB, SysUtils;


type TInMemoryTable = class(TTable)
private
hCursor: hDBICur;
procedure EncodeFieldDesc(var FieldDesc: FLDDesc;
const Name: string; DataType: TFieldType; Size: Word);
function CreateHandle: HDBICur; override;
public
procedure CreateTable;
end;

implementation

function TInMemoryTable.CreateHandle;
begin
Result := hCursor;
end;

procedure TInMemoryTable.EncodeFieldDesc(var FieldDesc: FLDDesc;
const Name: string; DataType: TFieldType; Size: Word);
const
TypeMap: array[TFieldType] of Byte = (
fldUNKNOWN, fldZSTRING, fldINT16, fldINT32, fldUINT16, fldBOOL,
fldFLOAT, fldFLOAT, fldBCD, fldDATE, fldTIME, fldTIMESTAMP, fldBYTES,
fldVARBYTES, fldINT32, fldBLOB, fldBLOB, fldBLOB, fldBLOB, fldBLOB,
fldBLOB, fldBLOB, fldCURSOR);
SubTypeMap: array[TFieldType] of Word = (
0, 0, 0, 0, 0, 0, 0, fldstMONEY, 0, 0, 0, 0, 0, 0, fldstAUTOINC,
fldstBINARY, fldstMEMO, fldstGRAPHIC, fldstFMTMEMO, fldstOLEOBJ,
fldstDBSOLEOBJ, fldstTYPEDBINARY, 0);
begin
with FieldDesc do
begin
AnsiToNative(Locale, Name, szName, SizeOf(szName) - 1);
iFldType := TypeMap[DataType];
iSubType := SubTypeMap[DataType];
case DataType of
ftString, ftBytes, ftVarBytes, ftBlob, ftMemo, ftGraphic,
ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary:
iUnits1 := Size;
ftBCD:
begin
iUnits1 := 32;
iUnits2 := Size;
end;
end;
end;
end;

procedure TInMemoryTable.CreateTable;
var
I: Integer;
pFieldDesc: pFLDDesc;
szTblName: DBITBLNAME;
iFields: Word;
Dogs: pfldDesc;
begin
CheckInactive;
if FieldDefs.Count = 0 then
for I := 0 to FieldCount - 1 do
with Fields do
if not Calculated then
FieldDefs.Add(FieldName, DataType, Size, Required);
pFieldDesc := nil;
SetDBFlag(dbfTable, True);
try
AnsiToNative(Locale, TableName, szTblName, SizeOf(szTblName) - 1);
iFields := FieldDefs.Count;
pFieldDesc := AllocMem(iFields * SizeOf(FLDDesc));
for I := 0 to FieldDefs.Count - 1 do
with FieldDefs do
begin
EncodeFieldDesc(PFieldDescList(pFieldDesc)^, Name,
DataType, Size);
end;
Check(DbiCreateInMemTable(DBHandle, szTblName, iFields, pFieldDesc, hCursor));
finally
if pFieldDesc <> nil then FreeMem(pFieldDesc, iFields * SizeOf(FLDDesc));
SetDBFlag(dbfTable, False);
end;
end;

end.

具体的使用方法如下所示:

MyInMemoryTable := TInMemoryTable.Create(TestForm);
with MyInMemoryTable do begin
DatabaseName := 'DBDEMOS';
{ TableName can be anything - but cannot be blank or DBE will give you
an invalid parameter error }
TableName := 'xxx.db';
{ add a couple of fields }
FieldDefs.Add('Field1', ftString, 10, False);
FieldDefs.Add('Field2', ftString, 15, False);
CreateTable;
{ open the table }
Active := True;
{ add a couple of records }
InsertRecord(['This table', 'is in memory!']);
InsertRecord(['Check it', 'out!']);
{ link the grid on the form to this table }
InMemoryDataSource.DataSet := MyInMemoryTable;
end;。

 
可以用 RX lib系列控件,其中有一 MEMOTABLE控件,可以在内存中建表
该控件可在 "深度历险" 站点得到,http://vcl.vclxx.com/delphigb/
很酷的站点,很酷的控件,或Email 我 yue_lin@csic.founderpku.com
 
你可以使用DATA ACCESS页中的TBatchMove元件,在它的Source特性中填入你
临时表的TTable/TQuery元件名。在它的Destination特性中填入你永久性的数据库
的TTable/TQuery元件名,再在程序中执行Execute即可。


EXP:TBATCHMOVE NAME特性为:BatchMove1
程序中加入以下代码:
batchmove.execute
 
如果临时表的字段名跟固定表不同,
还可以设置map等,非常方便。
 
Comment:

In memory table 有意思,不知那位试过没有?
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
顶部