📄 028.htm
字号:
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312"><TITLE>-->DELPHI专题文档-数据库应用-->为Delphi提供Pack和Undelete功能</TITLE>
<META NAME="keywords" CONTENT=" DELPHI专题文档-数据库应用 为Delphi提供Pack和Undelete功能">
<META NAME="description" CONTENT=" - DELPHI专题文档-数据库应用 - 为Delphi提供Pack和Undelete功能">
<style>
<!--
#page {position:absolute; z-index:0; left:0px; top:0px}
.tt3 {font: 9pt/12pt "宋体"}
.tt2 {font: 12pt/15pt "宋体"}
a {text-decoration:none}
a:hover {color: blue;text-decoration:underline}
-->
</style>
</HEAD>
<a href="index8.html">返回</a>
<body text="#000000" aLink=#9900ff link=#006699 vLink=#006699 bgcolor="#FFFFFF" leftmargin="3" topmargin="3" marginheight="3" marginwidth="3">
<TABLE WIDTH="100%" CELLPADDING=10 CELLSPACING=0 BORDER=0>
<TR>
<TD class="tt2" bgcolor="#F5F8F8" width="84%"><center><B><FONT style="FONT-SIZE: 16.5pt" COLOR="#FF6666" FACE="楷体_GB2312">为Delphi提供Pack和Undelete功能</FONT></B></center>
<hr color="#EE9B73" size="1" width="94%">
<font lang="ZH-CN"><p align="justify"></font><span style="font-size: 9pt"><font
color="#000000" lang="ZH-CN">本文针对</font><font color="#000000">Delphi3<font
lang="ZH-CN">和</font>Delphi4,<font lang="ZH-CN">对于</font>C<font lang="ZH-CN">++</font>Builder<font
lang="ZH-CN">同样也适用,在数据库引擎</font>BDE4.0<font lang="ZH-CN">、</font>4.5<font
lang="ZH-CN">、</font>5.0</font><font lang="ZH-CN" color="#000000">中经过测试。</font></span><font
lang="ZH-CN"></p>
<p align="justify"></font><span style="font-size: 9pt"><font color="#000000">Delphi<font
lang="ZH-CN">目前已经是国内常见的数据库编程工具,它在各方面表现不错,在支持大型多层数据库结构的同时也完全支持本地数据库的支持。对于本地数据库中</font>Delphi<font
lang="ZH-CN">对</font>FoxPro2.5b<font lang="ZH-CN">的支持也不错,我曾经对</font>VB<font
lang="ZH-CN">、</font>FoxPro2.5b<font lang="ZH-CN">、</font>Delphi<font lang="ZH-CN">的数据库操作速度进行比较,发现除了启动速度较慢外,其它各项</font>Delphi<font
lang="ZH-CN">均排在首位。而且</font>Delphi<font lang="ZH-CN">几乎支持所有原先</font>FoxPro<font
lang="ZH-CN">所拥有的功能,对于有一定编程经验的人来说,</font>Delphi<font
lang="ZH-CN">成了编写数据库软件的一把利器,因而</font>Delphi<font
lang="ZH-CN">迅速流行起来,我几年前甚至利用</font>Delphi 1.0</font><font
lang="ZH-CN" color="#000000">和汇编配合制作了工业控制系统的实时前后台软件。</font></span><font
lang="ZH-CN"></p>
<p align="justify"></font><span style="font-size: 9pt"><font color="#000000" lang="ZH-CN">但是在我长期使用</font><font
color="#000000">Delphi<font lang="ZH-CN">编程的过程中发现它也有不如人意的地方,特别是在本地数据库</font>FoxPro<font
lang="ZH-CN">方面,它居然不支持十分有用的</font>Pack<font lang="ZH-CN">和</font>Undelete<font
lang="ZH-CN">功能。对于数据库来说,因为是一个顺序存储文件,在删除部分记录是一般采用了软删除技术,也就是说将要删除的记录标记已删除的标记,但并不立即从物理上删除这些记录。这样做可以避免仅仅删除一条记录就要将整个数据库重新写入存储器,提高了读写的效率。但是如果数据库长期不对已经被标记为删除的记录进行整理和真实删除,数据库就会越来越大,其中无用的数据所占的比率越来越大,使得数据库的读写效率迅速下降,而且造成查询速度的减慢。在编写</font>FoxPro<font
lang="ZH-CN">数据库时有个规律,如果数据进出数据库频繁,也就是说不断删除旧的数据,加入新的数据的情况下每次在关闭数据库的时候或打开数据库的时候先做一次</font>Pack<font
lang="ZH-CN">,对数据库进行整理,将软删除的记录真正从数据库中删除。但是在</font>Delphi<font
lang="ZH-CN">的各个版本中数据库控件均未提供</font>Pack<font lang="ZH-CN">的功能,这使得用</font>Delphi<font
lang="ZH-CN">编写的数据库软件如果使用本地数据库的形式,数据库的大小增长很快,即使删除了大量记录,数据库的大小没有任何改变。以前我的做法是在使用这类数据库软件一段时间后利用</font>FoxPro<font
lang="ZH-CN">打开数据库进行</font>Pack,<font lang="ZH-CN">但是这样做要求客户端拥有</font>FoxPro<font
lang="ZH-CN">,而且经常这么做也很繁。于是我开始查找有关资料,为什么</font>Delphi<font
lang="ZH-CN">无法使用</font>pack</font><font lang="ZH-CN" color="#000000">功能?</font></span><font
lang="ZH-CN"></p>
<p align="justify"></font><span style="font-size: 9pt"><font color="#000000" lang="ZH-CN">经过再三查找,我找到一些资料,说明如何对数据库进行</font><font
color="#000000">pack<font lang="ZH-CN">了,在将其改编后在</font>Delphi</font><font
lang="ZH-CN" color="#000000">中使用通过。下面是其中的核心程序。</font></span><font
lang="ZH-CN"></p>
</font><p align="justify"><font color="#000000"><span style="font-size: 9pt">BDE API Call:</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">DBIResult DBIFN
DbiPackTable (hDb, hCursor, pszTableName, [</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">pszDriverType],
bRegenIdxs);</span></font></p>
<font lang="ZH-CN"><p align="justify"></font><span style="font-size: 9pt"><font
color="#000000" lang="ZH-CN">在数据库引擎的底层函数调用中,我找到了这个函数,这个函数据说可以对</font><font
color="#000000">FoxPro<font lang="ZH-CN">的数据库进行</font>Pack,<font lang="ZH-CN">其中</font>hDb<font
lang="ZH-CN">是数据库的句柄,可以由</font>Table.Handle<font lang="ZH-CN">获得;</font>hCursor<font
lang="ZH-CN">是数据表(</font>Table<font lang="ZH-CN">)关联的游标,如果为</font>NULL<font
lang="ZH-CN">则数据表依赖于</font>pszTableName<font lang="ZH-CN">和</font>pszDriverType<font
lang="ZH-CN">这两个传输决定数据库的来源;</font>bRegenIdxs<font lang="ZH-CN">决定是否关联外接的索引文件尤其是</font>MDX</font><font
lang="ZH-CN" color="#000000">多索引文件。</font></span><font lang="ZH-CN"></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">具体的操作函数如下:</span></font></p>
</font><p align="justify"><font color="#000000"><span style="font-size: 9pt">procedure
PackTable(Table: TTable);</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">var</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">Props: CURProps;</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">hDb: hDBIDb;</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">begin</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">if not Table.Active
then</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">raise
EDatabaseError.Create('Table<font lang="ZH-CN">必需已经打开</font>');</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">if not
Table.Exclusive then</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">raise
EDatabaseError.Create('Table<font lang="ZH-CN">必需以独占方式打开</font>');</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">Check(DbiGetCursorProps(Table.Handle,
Props));</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">if
(Props.szTableType = szDBASE) then</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">Check(DbiPackTable(Table.DBHandle,
Table.Handle, nil, szDBASE, True))</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">else</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">raise
EDatabaseError.Create('Table<font lang="ZH-CN">必需是</font>dBASE<font lang="ZH-CN">或</font>FoxPro<font
lang="ZH-CN">类型</font>');</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">Table.Open;</span></font></p>
<p align="justify"><font color="#000000"><span style="font-size: 9pt">end;</span></font></p>
<font lang="ZH-CN"><p align="justify"></font><span style="font-size: 9pt"><font
color="#000000" lang="ZH-CN">特别对这段源码说明一下,这段源码部分改编自</font><font
color="#000000">C<font lang="ZH-CN">,已经在上面提到过的环境中测试通过,需要注意的是,数据表必需以独占方式打开,简单的说,就是在设计时将数据表关闭(属性</font>Active=False<font
lang="ZH-CN">),在运行时才打开数据表</font>(form_onCreate<font lang="ZH-CN">时</font>Table.Open)<font
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -