经过再三查找,我找到一些资料,说明如何对数据库进行pack了,在将其改编后在Delphi中使用通过。下面是其中的核心程序。
BDE API Call:
DBIResult DBIFN DbiPackTable (hDb, hCursor, pszTableName, [
pszDriverType], bRegenIdxs);
在数据库引擎的底层函数调用中,我找到了这个函数,这个函数据说可以对FoxPro的数据库进行Pack,其中hDb是数据库的句柄,可以由Table.Handle获得;hCursor是数据表(Table)关联的游标,如果为NULL则数据表依赖于pszTableName和pszDriverType这两个传输决定数据库的来源;bRegenIdxs决定是否关联外接的索引文件尤其是MDX多索引文件。
具体的操作函数如下:
procedure PackTable(Table: TTable);
var
Props: CURProps;
hDb: hDBIDb;
begin
if not Table.Active then
raise EDatabaseError.Create('Table必需已经打开');
if not Table.Exclusive then
raise EDatabaseError.Create('Table必需以独占方式打开');
Check(DbiGetCursorProps(Table.Handle, Props));
if (Props.szTableType = szDBASE) then
Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))
else
raise EDatabaseError.Create('Table必需是dBASE或FoxPro类型');
Table.Open;
end;
特别对这段源码说明一下,这段源码部分改编自C,已经在上面提到过的环境中测试通过,需要注意的是,数据表必需以独占方式打开,简单的说,就是在设计时将数据表关闭(属性Active=False),在运行时才打开数据表(form_onCreate时Table.Open),这样才能保证数据表在独占方式下被打开。DbiGetCursorProps()是一个读取数据表的属性的底层函数调用,返回了大部分通用的数据表属性。Check()函数可以简单的处理数据库的出错提示和异常处理,如果出现函数调用错误会自动显示出错信息。
说了pack那么与之对应的Undelete也就更要解释了,同样我找到了将软删除的数据恢复的函数,不过这个函数隐藏的更深,连C代码都没有,所以以下的代码完全由我自己摸索出来,仅在上面说到的环境中测试通过。
首先介绍一下相应的底层函数调用:
DBIResult DBIFN DbiUndeleteRecord (hCursor);
这个函数仅有的参数就是关联的数据表的游标,您可以在BDE.int的文件中找到它的声明,但是具体的使用说明含糊不清,到底是恢复当前被删记录还是将数据表内所有被软删除的记录全部恢复?由于缺少相应的代码分析,我参照FoxPro的经验进行了多次实验,在十几种方案的对比下得出了结论,这条函数调用仅仅恢复当前的被软删除的记录。因此必需首先将数据表的游标移动到被删除的记录上,然后调用这条函数,才会有所反应。要知道在默认的情况下,数据库控件是不会将游标移动到被删除的记录上的,所以必需首先将数据表的读写属性修改,打开软删除的属性,使得遍历数据表时可以访问到被标记为删除的记录。下面是一段实现将数据表中所有被软删除的记录恢复的源代码。其它形式的反删除可以参照这段代码。
(编辑:aniston)
|