第十四章 简单数据库应用的创建及MASTAPP介绍(三)
利用GotoNearest方法执行不精确查找
窗体中的“不精确查找”按钮的事件处理过程代码如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
with table1 do
begin
IndexFieldNames:='Company';
setkey;
FieldByName('Company').AsString:=Edit1.text;
GotoNearest;
label3.caption:=FieldByName('Company').AsString;
end;
end;
读者可以利用 FindNearest方法执行上面的不精确查找, 具体使用方法可以参看Findkey方法的使用。
在上面的例子中要设置table1的IndexFieldNames属性为Company。
GotoNearest方法进行不精确查找
14.6 修改数据库中的记录
我们掌握了字段对象的概念和如何查找数据库中的记录之后,下面我便可以很方便地修改数据库中现存的记录了,一般来说,在程序中修改数据库中的记录包括下面这些步骤:
1、在数据库中找到要修改的记录,并将记录指针移至该记录。
2、调用Edit方法将与数据库表相连的TTable部件设置成编辑状态。
3、修改一个或多个字段。
4、调用post方法将修改后的记录写入数据库。
以上这几个步骤只是概述性的,具体实现时还有很多细节需要留心,我们通过一个例子来演示上面的全过程,以便让读者进一步地了解和掌握修改记录的方法。
例14.6我们为四个按钮分别编写了事件处理过程,用来遍历数据库中的记录并对每个客户记录的Company字段进行修改,在程序对记录进行更新操作时窗口中的控件都是无效的,在这个例子中我们还编写了一个简单的异常代码块用来确保在更新过程中出现异常时使控件恢复正常操作。
修改数据库记录
14.6.1 Edit方法Post方法
为了能让用户通过程序修改数据库表中的记录,TTable部件必须要处在编辑状态下。在大多数情况下,数据库表都是以浏览(只读方式)方式打开的,也就是说它的每一个字段可以被读取介不能被编辑修改。调用Edit方法能够将 TTable 部件置成编辑状态, 当TTable部件处于编辑状态后,我们才可以通过程序修改当前记录指针所指向的记录,但这样修改后的记录不会立即被写入到磁盘上的实际数据库表中。要想保存对记录的修改,必须要调用Post方法,Post方法才真正将我们对记录的修改写入实际的数据库表中。
一般来说,用来扫描整个数据库表并修改每个记录的某一个字段的程序如下所示:
with Table Do
begin
DisableControls;{在修改记录的过程中,使其它部件无效}
First; {将记录指针指向第一条记录}
while not EOF do
begin
<读取记录的一个字段值到一个变量中>
<做适当的修改>
Edit; {将TTable部件置成编辑状态}
<将修改后的字段值写回到其对应的字段>
post; {将修改后的记录写回数据库}
next; {修改下一条记录}
end;
enablecontrols; {恢复其它部件的功能}
end;
程序都是对TTable部件进行操作,因此使用With语句来防止错误的扩散是很有意义的。在这里要注意Disablecontrols方法和EnableControls方法的使用。DisableControls方法是在程序修改TTable部件中的记录时,切断TTable部件与数据访问部件TDatasource部件的联系。否则,在对TTable中的每一修改之后,TDataSource部件都会更新窗体中所有数据浏览部件的显示内容,这样会急剧减慢处理过程而且浪费时间。EnableControls方法是与DisableControle方法执行相反的操作,它是用来恢复TTable部件与TDatasource部件的联系并促使所有的数据浏览部件更新显示。
调用First方法是将记录指针移到数据库表中的第一条记录,确保程序从表中的第一条记录开始进行修改。调用Next方法是将记录指针从当前的记录移到下一条记录,这样保证了从表中的第一条记录开始逐条记录进行修改,直到修改完最后一条记录。如果不调用Next方法,程序将会陷入无穷的死循环。
14.6.2 实现异常保护的TRY...FINALLY语句
上面的程序存在着潜在的危险,在实际应用过程中,可能因为某些原因使得对数据库表的更新不能进行下去。如当程序试图执行Post方法将修改后的记录写回磁盘时,而又因为某种原因磁盘没有准备好,这时便出现了异常。当出现异常时,应用程序会暂停下来并且会弹出一对话框显示有关的错误信息,在用户单击错误信息对话框之后,程序将继续执行到某一个地方去,而这个地方常常不是用户所能预料到的。在我们的程序中, 在执行Post方法之前,窗体中所有的部件与TTable部件都已失去联系。因此,这种异常将导致窗体中显示的数据和数据库无关。
Object Pascal中的Try...Finally语句为我们解决上述异常问题提供了一个解决方法。在Delphi中仍然采用了这一语句用来处理异常问题。实际上,Try...Finally语句是把两组语句组合在一起。语句的Try部分包含了可能产生异常的程序代码,Finally部分包含了即使发生了异常也必须执行的一条或多条语句。在本例中, Finally 部分只包含了EnableControls方法调用这一条语句,我们将前面的代码改写并组合进Try...Finally语句:
with Table Do
begin
DisableControls;{在修改记录的过程中,使其它部件无效}
Try;
First; {将记录指针指向第一条记录}
while not EOF do
begin
<读取记录的一个字段值到一个变量中>
<做适当的修改>
Edit; {将TTable部件置成编辑状态}
<将修改后的字段值写回到其对应的字段>
post; {将修改后的记录写回数据库}
next; {修改下一条记录}
end;
enablecontrols;
Finally;{出现异常时,执行下面的程序}
enablecontrols; {恢复其它部件的功能}
end; {结束Try...Finally语句}
end;
在保留字Try和Finally之间的代码跟前面的代码是一样的,它们用于在记录之间移动记录指针并处理对记录的修改,这一段代码可能会出现异常,当异常发生时,我们想保证执行EnableControls,以便窗体中各控件恢复与 TTable 部件的联系, 因此我们必须将EnableControls语句放在Finally和结束语句End之间。
在这里要特别注意,请读者们不要混淆了Try...Finally语句和Try...Except语句。如果真正想在发生异常时采取相应的处理,就要使用Try...Except语句。Try...Finally语句只是用来处理当异常出现时,使应用程序执行Finally部分的语句,使程序继续执行下去。Try...Except语句是实现异常处理,Try...Finally语句是实现异常保护。
有了上述这些概念,我们便可以提供这个例子的一些程序代码,它涉及了所有这些内容。
程序清单:修改数据库中的记录
unit Unit26;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, ExtCtrls, DB, DBTables, Buttons;
type
TForm1 = class(TForm)
DataSource1: TDataSource;
customerTable: TTable;
Panel1: TPanel;
DBGrid1: TDBGrid;
Panel2: TPanel;
UpperCaseFirstAddBtn: TButton;
UpperCaseSecondAddBtn: TButton;
MixedCaseFirstAddBtn: TButton;
MixedCaseSecondAddBtn: TButton;
BitBtn1: TBitBtn;
procedure ForceCase(TargetField:String;ToUpper:Boolean);
procedure UpperCaseFirstAddBtnClick(Sender: TObject);
procedure MixedCaseFirstAddBtnClick(Sender: TObject);
procedure UpperCaseSecondAddBtnClick(Sender: TObject);
procedure MixedCaseSecondAddBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
const
upper=true;
Mixed=False;
at.yoka.com/url_5393203aaebc5ee32f000000.html
at.yoka.com/url_5393203baebc5e232b00000a.html
at.yoka.com/url_53932040aebc5ecb2b000012.html
at.yoka.com/url_53932042aebc5e9a2b00000e.html
at.yoka.com/url_5393203caebc5edc2f000002.html
at.yoka.com/url_53932043aebc5e4c1d000062.html
at.yoka.com/url_53932045aebc5e642e000006.html
at.yoka.com/url_53932044aebc5e1030000004.html
at.yoka.com/url_53932048aebc5e632e000008.html
at.yoka.com/url_53932048aebc5e0e2b000010.html
at.yoka.com/url_53932050aebc5e092d00000e.html
at.yoka.com/url_53932050aebc5e4c2b000010.html
at.yoka.com/url_53932058aebc5e0731000000.html
at.yoka.com/url_53932058aebc5ee02f000004.html
at.yoka.com/url_53932058aebc5edc2b00000e.html
at.yoka.com/url_5393205baebc5e352b000010.html
at.yoka.com/url_5393205caebc5ed41e00005e.html
at.yoka.com/url_53932055aebc5e0231000000.html
at.yoka.com/url_5393205daebc5ef716000074.html
at.yoka.com/url_5393205faebc5e822b00000e.html
at.yoka.com/url_53932065aebc5ee330000001.html
at.yoka.com/url_53932066aebc5e8f2d000008.html
at.yoka.com/url_5393206caebc5e192d000008.html
at.yoka.com/url_5393206eaebc5e532200005c.html
at.yoka.com/url_53932071aebc5e392b000012.html
at.yoka.com/url_53932073aebc5ed830000000.html
at.yoka.com/url_53932073aebc5eff30000000.html
at.yoka.com/url_53932070aebc5e0931000004.html
at.yoka.com/url_53932074aebc5e0631000002.html
at.yoka.com/url_5393207baebc5e812b000010.html
at.yoka.com/url_5393207baebc5e842b00000e.html
at.yoka.com/url_53932081aebc5e992b000012.html
at.yoka.com/url_53932083aebc5ef430000002.html
at.yoka.com/url_53932086aebc5edb2b000011.html
at.yoka.com/url_53932088aebc5eda2b000010.html
at.yoka.com/url_53932088aebc5ee430000006.html
at.yoka.com/url_53932089aebc5ef030000002.html
at.yoka.com/url_5393208aaebc5ee82a000010.html
at.yoka.com/url_53932090aebc5ea431000002.html
at.yoka.com/url_53932090aebc5e0e31000006.html
at.yoka.com/url_53932090aebc5e812b000012.html
at.yoka.com/url_53932098aebc5e8f2d00000a.html
at.yoka.com/url_5393209caebc5e9032000000.html
at.yoka.com/url_5393209daebc5e1230000008.html
at.yoka.com/url_5393209daebc5e2d2b00000e.html
at.yoka.com/url_5393209faebc5ea132000000.html
at.yoka.com/url_539320a6aebc5e842b000012.html
{$R *.DFM}
Function IsUpper(ch:char):Boolean;
begin
If (ch>='A')and(ch<='Z')then
IsUpper:=true
else
IsUpper:=False;
end;
procedure TForm1.ForceCase(TargetField:String;ToUpper:Boolean);
var
WorkBuffer:string;
i:Integer;
begin
with customerTable do
begin
DisableControls;
TRY
First; {将记录指针移到第一条记录处 }
While not EOF do
begin
WorkBuffer:=FieldByName(TargetField).AsString;
If ToUpper then
for i:=1 to Length(WorkBuffer)do
WorkBuffer[i]:=UpCase(WorkBuffer[i])
else
begin
for i:=1 to Length(WorkBuffer) do
If IsUpper(WorkBuffer[i]) then
WorkBuffer[i]:=chr(ord(WorkBuffer[i])+32);
WorkBuffer[1]:=UpCase(WorkBuffer[1])
end;
Edit;
FieldByName(TargetField).AsString:=WorkBuffer;
post;
Next;
end;
Finally
enableControls;
end;
end;
end;
procedure TForm1.UpperCaseFirstAddBtnClick(Sender: TObject);
begin
ForceCase('Addr1',Upper);
end;
procedure TForm1.MixedCaseFirstAddBtnClick(Sender: TObject);
begin
ForceCase('Addr1',Mixed);
end;
procedure TForm1.UpperCaseSecondAddBtnClick(Sender: TObject);
begin
ForceCase('Addr2',Upper);
end;
procedure TForm1.MixedCaseSecondAddBtnClick(Sender: TObject);
begin
ForceCase('Addr2',Mixed);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
customerTable.open;
end;
end.
14.7 插入和删除记录
虽然我们使用DBD或者在应用程序窗体中用TDBNavigator可以插入、删除表中的记录,但是任何重要的数据库应用程序都是根据最终用户的命令完成此类操作的。同样,如果我们掌握了字段对象及其用法,修改数据库中的记录,插入和删除记录将变得非常容易。
要想删除表中的某一条记录,首先将记录指针移到该记录处,然后调用delete方法,这样,当前指针所在的记录就会被删除,而且我们在进行删除操作时,不必将TTable部件设置成编辑状态。当前指针所在的记录被删除之后,被删除记录下面的所有记录都向前移动,记录指针自动移到紧挨着被删除的记录的下一条记录。在删除记录的过程中没有提醒用户是否真的想删除当前记录的信息确认框,因此在进行此项操作时要倍加小心,如果是开发应用程序,最好的办法是提供一个确认信息框确保用户不会意外删除记录。
插入一条记录也很简单,Delphi为用户提供两种方法用来插入记录到现存数据库表中,一种方法是在当前记录指针所在的记录处插入记录;另一种方法是在数据库表的尾部插入记录。这两种方法是分别调用Insert方法和Append方法实现的。但是无论是调用Insert方法还是调用Append方法在具有索引的数据库表中插入记录,增加到索引表中的记录都将按照索引顺序写入到数据库表中,也就是说对于索引表,调用Insert和Append方法的效果是一样的。事实上,Append方法只适用于那些没有索引的表,这种没有索引的表并不十分有用因而通常不创建这种表。几乎任何情况下我们都是用Insert方法来插入记录。
用户在插入记录时一般可以采用两种方式插入:逐步插入即首先建立一条空记录,然后再填充记录的各个字段,最后再将记录写回到磁盘,共分三个独立的操作步骤;而使用InsertRecord方法便可以一次将插入记录的操作完成。
14.7.1 逐步插入方法
逐步插入方法分为三个明确的步骤:先调用TTable部件的Insert方法在TTable中创建一条新的空记录,然后填充该记录的各个字段,最后调用post方法把新记录写到磁盘上的实际数据库文件中,在填充并传送记录以前,考虑插入记录到表中的什么位置是毫无意义的,假设插入的表是有索引的,在调用post方法时,Delphi会自动地把插入的新记录按照索引顺序插入到表中的正确位置。如果插入的表中没有索引,那么新记录将插入到当前指针所在记录的后面。
因此,采用逐步插入方法插入记录的程序代码一般如下形式:
With Table do
begin
Insert; {插入一条空白记录}
<填充该记录的各个字段>
post; {将插入的记录写回到磁盘文件}
end;
对于没有索引的数据库表,可以用Append方法替代Insert方法把新记录插入到表的尾部。
14.7.2 调用InsertRecord插入记录
对于简单的应用程序,Delphi允许用户用一条语句插入一个新记录,而且这个新记录可以带有任意多个新字段值。InsertRecord方法把新记录中字段的赋值语句和psot方法调用组合进一条语句中。
InsertRecord方法把记录的各个字段值组合成一个字段值数组作为它的唯一参数。在字段值数组中,可以为插入的记录的每个字段提供一个字段值,或从最左一列开始依次为任意多个字段赋值。也就是说用户可以从表的最左边一列起, 把多个列的值同时传递给InsertRecord,直到所有字段都被赋值。用户也可以省略后面的字段,InsertRecord会用空值填充这些没有赋值的字段。用户还可以对那些明确希望用空值填充的字段传递保留字NIL来标明该字段为空。
如我们希望在Customer.DB表中插入一条记录,可以用下面的代码来实现:
InsertRecord(['2000',NIL,NIL,NIL]);
在上面的程序代码中,我们只填充了四个字段:CustNo、Company、Add1、 Add2 。InsertRecord会自动将其它字段赋以空值。
例14.7 在这个例子中,我们在CustNo.DB表中插入和删除记录,都是在程序中完成这类操作的,而不再是使用DBD或数据浏览部件完成。
插入/删除记录
程序清单:
unit tt;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
StdCtrls, Forms, DBCtrls, DB, DBGrids, Buttons, DBTables, Grids,
ExtCtrls,Mask,Dialogs;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DBNavigator: TDBNavigator;
Panel1: TPanel;
DataSource1: TDataSource;
Panel2: TPanel;
customerTable: TTable;
BitBtn1: TBitBtn;
Label1: TLabel;
Label2: TLabel;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
CustNoEdit: TEdit;
CompEdit: TEdit;
procedure FormCreate(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ private declarations }
第十四章 简单数据库应用的创建及MASTAPP介绍(三)相关推荐
- 93.第十九章 MySQL数据库 -- MySQL安装和基本使用(三)
2.5 通用二进制格式安装 MySQL 5.6 2.5.1 安装相关包 #centos7 yum install -y libaio perl-Data-Dumper#centos8 yum inst ...
- 【Java数据结构与算法】第十四章 红黑树
第十四章 红黑树 文章目录 第十四章 红黑树 一.红黑树 1.介绍 2.插入结点 3.删除结点 4.与平衡二叉树的对比 一.红黑树 1.介绍 红黑树(Red Black Tree)是平衡二叉树的其中一 ...
- VLSI数字信号处理系统——第十四章冗余运算
VLSI数字信号处理系统--第十四章冗余运算 作者:夏风喃喃 参考: (1) VLSI数字信号处理系统:设计与实现 (美)Keshab K.Parhi/著 (2) socvista https://w ...
- 《网络安全工程师笔记》 第十四章:渗透简单测试流程
注:本笔记来自温晓飞老师的网络安全课程 第十四章:渗透简单测试流程 第一章:虚拟化架构与系统部署 第二章:IP地址详解 第三章:进制转换 第四章:DOS基本命令与批处理 第五章:用户与组管理 第六章: ...
- Oracle 11g数据库基础教程(第2版)-课后习题-第十四章
--第十四章 --1.对HUMAN_RESOURCE数据库进行冷备份--1.启动sqlplus,以sysdba身份登录数据库--2.查询当前数据库所有数据文件.控制文件.联机重做日志文件的位置sele ...
- 鸟哥的Linux私房菜(服务器)- 第十四章、账号控管: NIS 服务器
第十四章.账号控管: NIS 服务器 最近更新日期:2011/07/28 有没有想过,如果我有十部 Linux 主机,这十部主机仅负责不同的功能,事实上,所有的主机账号与对应的密码都相同! 那么我是将 ...
- 数据库系统概念总结:第十四章 事务
周末无事水文章,期末备考的总结资料 第十四章 事务 14.1 事务概念 事务是访问并可能更新各种数据项的一个程序执行单元 ACID特性 –原子性(Atomicity):事务的所有操作都在数据库中正确反 ...
- 《深入理解 Spring Cloud 与微服务构建》第十四章 服务链路追踪 Spring Cloud Sleuth
<深入理解 Spring Cloud 与微服务构建>第十四章 服务链路追踪 Spring Cloud Sleuth 文章目录 <深入理解 Spring Cloud 与微服务构建> ...
- 数据结构思维 第十四章 持久化
第十四章 持久化 原文:Chapter 14 Persistence 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 在接下来的几个练习中,我们将返回到网页搜索引擎的构建.为了回 ...
最新文章
- mysql程序语句范文,SQL语句(MySQL)
- 图像傅里叶变换,幅度谱,相位谱
- UVa 122 Trees on the level
- matlab在图像调用Gabor滤波
- new String(123) 创建了几个对象?
- VMWare 8 安装 Mac OS 10.7 (Lion)版 【转】
- Spring Boot内嵌Tomcat原理
- 【关键词排名点击软件】网站关键词挖掘常用的五个工具
- x240无线网卡驱动 linux,Linux2.6移植:DM9000驱动
- 8年码龄的技术总监,去上市公司面试,结果凉了!
- 爬取豆瓣排名前100的电影
- 如何通过软件编辑自己想要的点阵图片
- php 查询数据传值,php-如何在Laravel中传递数据进行查看?
- 苹果mp3软件_M4R如何转为MP3?音频转换的高效方法
- html 拉伸幕,html 对 div 进行 拉伸 拖拽
- 2021年高处安装、维护、拆除模拟考试题库及高处安装、维护、拆除作业考试题库
- MAML 源代码解释说明 (一)
- WINDOWS操作系统发展历程
- 【关于单片机的N多问题】关于单片机的N多问题
- ocp|ocm考证系列文章!
热门文章
- 树莓派魔镜MagicMirror —— 4 系统安装与配置
- CAN记录仪 can数据记录仪简介和功能应用 can总线记录
- 学通信工程考计算机等级证书,通信工程专业可以考什么证书
- 关于layui的table组件不支持IE导出的问题简单修复
- [SAP]MM模块术语
- Go 性能优化之race实战
- 山西2021高考成绩查询任玥,高考倒计时60天!华师为你加油!
- Vue学习——Uncaught TypeError: “i“ is read-only
- 基于java房屋租赁系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
- 修改origin分支名