⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pack_database.htm

📁 对于学习很有帮助
💻 HTM
📖 第 1 页 / 共 2 页
字号:
.font2 {font-size:9pt; line-height:13pt; }
A{text-transform: none; text-decoration:none;color:#0000FF}
a:hover {text-decoration:underline;color:#FFFFF}
--></style></head><body bgcolor=#FFFFFF><p><span class=font1> </span></p><blockquote> <center><span class=font1><font color=#ff0000><b><font lang=ZH-CN>为</font>Delphi<font lang=ZH-CN>提供</font>Pack<font lang=ZH-CN>和</font>Undelete<font lang=ZH-CN>功能</font></b></font></span></center></blockquote><blockquote> <blockquote> <font color=#008080 lang=ZH-CN><b><p align=right></b></font><span class=font1><font color=#000000>weiwu</font></span><font color=#008080 lang=ZH-CN><b></p> </b></font> </blockquote> <font color=#000080 lang=ZH-CN><b><p align=justify></b></font><span class=font1><font color=#000000><font lang=ZH-CN>本文针对</font>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 color=#000000 lang=ZH-CN>中经过测试。</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><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 color=#000000 lang=ZH-CN>和汇编配合制作了工业控制系统的实时前后台软件。</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><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 color=#000000 lang=ZH-CN>功能?</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>经过再三查找,我找到一些资料,说明如何对数据库进行</font><font color=#000000>pack<font lang=ZH-CN>了,在将其改编后在</font>Delphi</font><font color=#000000 lang=ZH-CN>中使用通过。下面是其中的核心程序。</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>BDE API Call:</font></span></p> <p align=justify><span class=font1><font color=#000000>DBIResult DBIFN DbiPackTable (hDb, hCursor, pszTableName, [</font></span></p> <p align=justify><span class=font1><font color=#000000>pszDriverType], bRegenIdxs);</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><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 color=#000000 lang=ZH-CN>多索引文件。</font></span><font lang=ZH-CN></p> <p align=justify><span class=font1><font color=#000000>具体的操作函数如下:</font></span></p> </font><p align=justify><span class=font1><font color=#000000>procedure PackTable(Table: TTable);</font></span></p> <p align=justify><span class=font1><font color=#000000>var</font></span></p> <p align=justify><span class=font1><font color=#000000>Props: CURProps;</font></span></p> <p align=justify><span class=font1><font color=#000000>hDb: hDBIDb;</font></span></p> <p align=justify><span class=font1><font color=#000000>begin</font></span></p> <p align=justify><span class=font1><font color=#000000>if not Table.Active then</font></span></p> <p align=justify><span class=font1><font color=#000000>raise EDatabaseError.Create('Table</font><font color=#000000 lang=ZH-CN>必需已经打开</font><font color=#000000>');</font></span></p> <p align=justify><span class=font1><font color=#000000>if not Table.Exclusive then</font></span></p> <p align=justify><span class=font1><font color=#000000>raise EDatabaseError.Create('Table</font><font color=#000000 lang=ZH-CN>必需以独占方式打开</font><font color=#000000>');</font></span></p> <p align=justify><span class=font1><font color=#000000>Check(DbiGetCursorProps(Table.Handle, Props));</font></span></p> <p align=justify><span class=font1><font color=#000000>if (Props.szTableType = szDBASE) then</font></span></p> <p align=justify><span class=font1><font color=#000000>Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))</font></span></p> <p align=justify><span class=font1><font color=#000000>else</font></span></p> <p align=justify><span class=font1><font color=#000000>raise EDatabaseError.Create('Table<font lang=ZH-CN>必需是</font>dBASE<font lang=ZH-CN>或</font>FoxPro<font lang=ZH-CN>类型</font>');</font></span></p> <p align=justify><span class=font1><font color=#000000>Table.Open;</font></span></p> <p align=justify><span class=font1><font color=#000000>end;</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><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 lang=ZH-CN>,这样才能保证数据表在独占方式下被打开。</font>DbiGetCursorProps<font lang=ZH-CN>()是一个读取数据表的属性的底层函数调用,返回了大部分通用的数据表属性。</font>Check<font lang=ZH-CN>()</font></font><font color=#000000 lang=ZH-CN>函数可以简单的处理数据库的出错提示和异常处理,如果出现函数调用错误会自动显示出错信息。</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>说了</font><font color=#000000>pack<font lang=ZH-CN>那么与之对应的</font>Undelete<font lang=ZH-CN>也就更要解释了,同样我找到了将软删除的数据恢复的函数,不过这个函数隐藏的更深,连</font>C</font><font color=#000000 lang=ZH-CN>代码都没有,所以以下的代码完全由我自己摸索出来,仅在上面说到的环境中测试通过。</font></span><font lang=ZH-CN></p> <p align=justify><span class=font1><font color=#000000>首先介绍一下相应的底层函数调用:</font></span></p> </font><p align=justify><span class=font1><font color=#000000>DBIResult DBIFN DbiUndeleteRecord (hCursor);</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>这个函数仅有的参数就是关联的数据表的游标,您可以在</font><font color=#000000>BDE.int<font lang=ZH-CN>的文件中找到它的声明,但是具体的使用说明含糊不清,到底是恢复当前被删记录还是将数据表内所有被软删除的记录全部恢复?由于缺少相应的代码分析,我参照</font>FoxPro</font><font color=#000000 lang=ZH-CN>的经验进行了多次实验,在十几种方案的对比下得出了结论,这条函数调用仅仅恢复当前的被软删除的记录。因此必需首先将数据表的游标移动到被删除的记录上,然后调用这条函数,才会有所反应。要知道在默认的情况下,数据库控件是不会将游标移动到被删除的记录上的,所以必需首先将数据表的读写属性修改,打开软删除的属性,使得遍历数据表时可以访问到被标记为删除的记录。下面是一段实现将数据表中所有被软删除的记录恢复的源代码。其它形式的反删除可以参照这段代码。</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>procedure Ttablepro.undelete;</font></span></p> <p align=justify><span class=font1><font color=#000000>var</font></span></p> <p align=justify><span class=font1><font color=#000000>CProps: CurProps;</font></span></p> <p align=justify><span class=font1><font color=#000000>rslt: DBIResult;</font></span></p> <p align=justify><span class=font1><font color=#000000>bm:TBookmark;</font></span></p> <p align=justify><span class=font1><font color=#000000>rp:pRECProps;</font></span></p> <p align=justify><span class=font1><font color=#000000>begin</font></span></p> <p align=justify><span class=font1><font color=#000000>Check(DbiGetCursorProps(self.Handle, CProps));//</font><font color=#000000 lang=ZH-CN>取得数据表的属性</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>if (StrIComp(CProps.szTableType, szDBASE) &lt;&gt; 0) then//<font lang=ZH-CN>如果不是</font>Dbase<font lang=ZH-CN>或</font>Foxpro</font><font color=#000000 lang=ZH-CN>则退出</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);</font></span></p> <p align=justify><span class=font1><font color=#000000>rslt:=DbiValidateProp(hDBIObj(self.Handle), curSOFTDELETEON, True);</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>可否设置软删除?</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>if (rslt = DBIERR_NONE) then</font></span></p> <p align=justify><span class=font1><font color=#000000>Check(DbiSetProp(hDBIObj(self.Handle), curSOFTDELETEON, Longint(true)));</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>设置为可以软删除</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>Check(DbiGetCursorProps(self.Handle, CProps));</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>更新数据表的属性</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>if (CProps.bDeletedOn = False) then</font></span></p> <p align=justify><span class=font1><font color=#000000>raise EDatabaseError.Create('</font><font color=#000000 lang=ZH-CN>软删除没有设置!</font><font color=#000000>');</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>取得当前的记录位置</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>bm:=self.GetBookmark;</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>将游标移动到第一个记录以前!</font><font color=#000000>Not Table.First!</font></span></p> <p align=justify><span class=font1><font color=#000000>Check(DbiSetTobegin(self.handle));</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>不断移动,直到到数据表的最后记录</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>while (DBIGETNEXTRECORD(self.handle,dbinolock,nil,nil)=DBIERR_NONE) do</font></span></p> <p align=justify><span class=font1><font color=#000000>begin</font></span></p> <p align=justify><span class=font1><font color=#000000>//<font lang=ZH-CN>请关闭</font>Delphi</font><font color=#000000 lang=ZH-CN>的异常响应,以便执行下面的语句!</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>try</font></span></p> <p align=justify><span class=font1><font color=#000000>check(DbiUndeleteRecord(self.Handle));</font></span></p> <p align=justify><span class=font1><font color=#000000>except</font></span></p> <p align=justify><span class=font1><font color=#000000>//Do somthing here !</font></span></p> <p align=justify><span class=font1><font color=#000000>end;</font></span></p> <p align=justify><span class=font1><font color=#000000>end;</font></span></p> <p align=justify><span class=font1><font color=#000000>//</font><font color=#000000 lang=ZH-CN>取回原先记录的位置,重新定位</font></span><font lang=ZH-CN></p> </font><p align=justify><span class=font1><font color=#000000>self.GotoBookmark(bm);</font></span></p> <p align=justify><span class=font1><font color=#000000>self.FreeBookmark(bm);</font></span></p> <p align=justify><span class=font1><font color=#000000>self.Refresh;</font></span></p> <p align=justify><span class=font1><font color=#000000>end;</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>(注:如果可以,请在刊登时删去</font><font color=#000000>“Self.refresh”<font lang=ZH-CN>一行,对于原理的介绍无需此行,仅在我的控件的属性中需要,以上代码来自我制作的</font>Delphi<font lang=ZH-CN>控件</font>TTablePro</font><font color=#000000 lang=ZH-CN>)</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>在这段代码中已经有了详细的解释,应该可以比较容易的了解</font><font color=#000000>undelete<font lang=ZH-CN>的技巧了。当然如果能够不必与源代码打交道是最好的,因此我制作了一个</font>Delphi<font lang=ZH-CN>的控件</font>TtablePro<font lang=ZH-CN>在</font>Table<font lang=ZH-CN>的基础上增加了两个方法</font>PackTable<font lang=ZH-CN>和</font>Undelete;</font><font color=#000000 lang=ZH-CN>包含了上面介绍的功能。您可以到我的主页免费下载试用,测试版可以免费使用无限制。</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>如果这篇文章有何问题请与我联络修改。谢谢。另外我可以提供防止应用程序重复加载的技术文章,同样可以提供相应我制作的免费控件。在任务栏显示图标并直接与弹出式菜单的关联的控件与完整技术资料,还可以实现动态图标,目前的免费控件仅支持与指定的菜单关联,就象</font><font color=#000000>dataset<font lang=ZH-CN>与</font>datasource<font lang=ZH-CN>一样。我可以提供不少我制作的控件的实现技巧、技术的文章。另外我可以提供围棋自动提子的算法和技巧的文章,代码来自我制作的自由软件-围棋打谱软件</font>2.0b…</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>我的联络地址</font><font color=#000000>:Email:mailto:weiwu@kali.com.cn</font></span></p> <font lang=ZH-CN><p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>我的主页:</font><font color=#000000>http://202.96.217.5/~web 169<font lang=ZH-CN>和上海热线的</font>Vip<font lang=ZH-CN>均可直接访问!目前部分控件尚未上载,不过有些我制作的控件可以在其它国内外的</font>Delphi</font><font color=#000000 lang=ZH-CN>站点看到。</font></span><font lang=ZH-CN></p> <p align=justify></font><span class=font1><font color=#000000 lang=ZH-CN>目前我的研究方向是网上的围棋对弈软件、企业决策软件、</font><font color=#000000>SQL<font lang=ZH-CN>生成器封装得更好的</font>DirectX5<font lang=ZH-CN>控件</font>(<font lang=ZH-CN>改编自</font>DelphiX,<font lang=ZH-CN>我的改编版本是目前唯一支持</font>Delphi4<font lang=ZH-CN>的</font>)</font></span><b><font color=#0000ff size=4></p> </font></b></blockquote><p> </p><p><span class=font2>版主:西安&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 梁&nbsp; 明<br>日期:99-07-29<br>E-mail:<a href=mailto:delphifan@990.net>delphifan@990.net</a></span></p><hr></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -