Delphi中嵌入的数据库应用开发工具如Database Form Expert具有很强大的功能 我们不需要编写任何程序代码便可以快速地创建一个简单的数据库应用程序 甚至还能创建基于多个数据库表的主要──明细型数据库应用程序
本章主要介绍用Delphi开发简单的数据库应用程序的一般方法和步骤 首先让读者对Delphi强劲的数据库应用开发工具有一个直观的印象 然后在此基础上进行复杂的数据库应用程序的设计 本章主要包括以下内容
● 创建数据库应用窗体
包括用Database Form Expert 或手工方式创建简单的无需编写程序代码的应用程序或者利用多个部件并编写功能复杂的程序代码创建主要──明细型数据库应用程序
● 在应用程序中控制字段有关的属性
描述怎样读写数据库表中字段的值和控制字段的显示格式等
本章所介绍的例子中用到的窗体 数据库表以及相关的文件都是在安装Delphi时缺省安装在C:\DELPHI\DEMOS\DB\MASTAPP目录中 并且用别名DBDEMOS表示这一子目录 在本章例子中 除特殊声明外 所有的TTable和 TQuery 部件的 DatabaseName 属性都设置为DBDEMOS
简单的基于单表的据库应用
用Decphi创建显示一个数据库表中的内容的应用非常简单和方便 只需要三个部件 只要将这三个部件通过相关的属性相互联系起来 不需要编写任何程序代码便可以实现 例如 用户想查看数据库表Customer DB中的内容时 可以按下面步骤来实现
选择相关的部件
选择菜单Project/New开始一个新工程 并修改Form 的Caption属性为CustomerFrom 并把Name属性设置为CustomerForm 然后从部件选择板上的Data Access 页上选取一个Datasounce部件和一个Table部件放到窗体的左上角 它们是非可见的部件 在窗体中我们看到的只是部件的图标 从Data Control页上选取DBGrid部件放到窗体中前两个部件的下面 完成这些工作之后 窗体如图 所示
图在CustomerFrom 窗体中放置三个部件
设置部件的属性
为了使TDBGrid部件能够显示数据库表Customer DB中的客户信息 我们必须修改窗体三个部件相关的属性 这些属性的设置如表 所示
表 CustomerFrom 窗体中三个部件的属性设置
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
属 性 属 性 值
──────────────────────────────
DataSource AutoEdit False
DataSource DataSet Table
Table DatabaseName DBDEMOS
Table TableName CUSTOMER DB
Table Active True
DBGrid DataSource DataSource
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
这里要注意的是 DBDEMOS是Delphi缺省安装时C:\Delphi\DEMO\DB\MASTAPP目录的别名 而且数据库表Customer DB存在该目录下 用户在使用这一例子时 请注意这两项设置都是正确的 另外 Datasource Dataset Table TableName和DBGrid Datasource属性都有下拉式列表框允许用户从可能的值列表中选择它们的值 这样能方便我们进行属性的设置 而且不容易出错
Datasouuce AutoEdit属性设置为False是为了防止用户修改数据库表中的数据 在下面的讨论中我们将详细地进行说明
Table Active设置为True时 Delphi会打开Table TableName所指定的数据库表 如果这个数据库表不存在(或表中什么也没有 即空表) Delphi 会d出出错信息并且Table Active变成False 当Table Active被设置成True之后 Table 部件的一些属性就不能再修改了 如Table DatabaseName和Table Tablename属性 若要修改它们 必须首先要将Table Active属性设置为False 然后再进行修改 否则 Delphi会d出错误信息 Cannot perform this operation on an open database 当看到这个错误信息时 只需把Table Active置成False 完成相关的修改后 再把 Table Active 属性设置为True
当我们把DBGrid DataSource的值设置成DataSource 时 Delphi会把Customer DB中的数据填充到DBGrid 部件中 并且可以用DBGrid 中的滚动条来浏览数据库表中的所有记录
运行程序
保存文件 命名代码单元为Cust pas 命名工程名为CustPRJ DPR 然后按F 编译并运行程序 程序执行之后 我们可以使用滚动条或键盘移动键在字段和记录间移动 但不能修改表中的数据 因为Datasouc AutoEdit 属性已被设置为False
Cust程序中的三个部件都有各自的特殊用途 三个部件的相关属性在内部相互联系生成最终的应用程序 TTable部件连接磁盘上的实际数据库表和应用程序中其他部件的通道 TTable部件具有打开和关闭 读取 更新以及其他处理磁盘数据库文件的方法
TDatasource部件是连接TTable部件和数据浏览部件如TDBGrid部件的桥梁 TDBGrid部件用于显示数据库表中的数据信息 它为应用程序提供一个直观的界面 图 阐述了这三个部件之间的关系
Cust程序中三个部件之间的内部关系
TDBGrid 部件的奇妙之处在于它知道如何去获取数据库表中的下一条或前一条记录 我们使用滚动条或箭头键便可以完成这项任务 TDBGrid部件不知道如何增加 删除和修改记录 如果想让 Cust 程序能够修改数据库表中的记录 只要把 Datasource 部件的AutoEdit属性设置成True 并重新编译和运行程序就可以达到目的 使用箭头键 把DBGrid的高亮度条定位到某一个字段上 然后键入新值 该字段中的值将被键入的新值所取代 并且当移动到另一条记录时 健入的信息会自动写入数据库表中 如果想放弃所做的改动 只需在离开该字段前按一下Escape键
如果想在表中增加新记录 可以把高亮度条移到网格底端的空白记录上并输入新记录的有关字段值 也可以在用户指定的某一条记录的后面插入一条新记录 只要把高亮度条定位到指定的记录上 按Ins键 使可以在该记录的后面插入新记录
删除某一条记录时 把高亮度条定位在想删除的记录的任何字段上 按Ctrl+ del键 这时会出现保护信息 我们可以确认是否真的想删除该项记录
TDBGrid为用户提供了较完备的功能 用于控制是否编辑 增加或删除记录 若想禁止对数据库表作任何修改 设置TDBGrid部件的Readonly属性为 True 并设置 Option dgEDiting为False(这将为我们提供一个只读的数据库表浏览器而不是数据库编辑器 但它隐含着增加 编辑和删除记录的能力) TDBGrid部件的这些属性和Option属性其它选项的各种不同组合可以让我们很方便地对数据库表进行有效的浏览 编辑等 *** 作
如果我们经常使用像电子表格那样的界面来显示和编辑数据记录 TDBGrid 部件便是一个很方便的工具 但那并不是最友好的用户界面 如果想拥有更优美更直观的界面 我们还可以使用单独的数据浏览部件来显示数据库表中各个字段的值 并利用TDBNavigator部件控制对数据库表的存取
lishixinzhi/Article/program/Delphi/201311/25173
利用GotoNearest方法执行不精确查找
窗体中的 不精确查找 按钮的事件处理过程代码如下
procedure TForm Button Click(Sender: TObject)
begin
with table do
begin
IndexFieldNames:= Company
setkey
FieldByName( Company ) AsString:=Edit text
GotoNearest
label caption:=FieldByName( Company ) AsString
end
end
读者可以利用 FindNearest 方法执行上面的不精确查找 具体使用方法可以参看Findkey方法的使用
在上面的例子中要设置table 的IndexFieldNames属性为Company
GotoNearest方法进行不精确查找
修改数据库中的记录
我们掌握了字段对象的概念和如何查找数据库中的记录之后 下面我便可以很方便地修改数据库中现存的记录了 一般来说 在程序中修改数据库中的记录包括下面这些步骤
在数据库中找到要修改的记录 并将记录指针移至该记录
调用Edit方法将与数据库表相连的TTable部件设置成编辑状态
修改一个或多个字段
调用post方法将修改后的记录写入数据库
以上这几个步骤只是概述性的 具体实现时还有很多细节需要留心 我们通过一个例子来演示上面的全过程 以便让读者进一步地了解和掌握修改记录的方法
例 我们为四个按钮分别编写了事件处理过程 用来遍历数据库中的记录并对每个客户记录的Company字段进行修改 在程序对记录进行更新 *** 作时窗口中的控件都是无效的 在这个例子中我们还编写了一个简单的异常代码块用来确保在更新过程中出现异常时使控件恢复正常 *** 作
修改数据库记录
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方法 程序将会陷入无穷的死循环
实现异常保护的TRY…FINALLY语句
上面的程序存在着潜在的危险 在实际应用过程中 可能因为某些原因使得对数据库表的更新不能进行下去 如当程序试图执行Post方法将修改后的记录写回磁盘时 而又因为某种原因磁盘没有准备好 这时便出现了异常 当出现异常时 应用程序会暂停下来并且会d出一对话框显示有关的错误信息 在用户单击错误信息对话框之后 程序将继续执行到某一个地方去 而这个地方常常不是用户所能预料到的 在我们的程序中 在执行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语句是实现异常保护
有了上述这些概念 我们便可以提供这个例子的一些程序代码 它涉及了所有这些内容
lishixinzhi/Article/program/Delphi/201311/25167
要想删除表中的某一条记录 首先将记录指针移到该记录处 然后调用delete方法 这样 当前指针所在的记录就会被删除 而且我们在进行删除 *** 作时 不必将TTable部件设置成编辑状态 当前指针所在的记录被删除之后 被删除记录下面的所有记录都向前移动 记录指针自动移到紧挨着被删除的记录的下一条记录 在删除记录的过程中没有提醒用户是否真的想删除当前记录的信息确认框 因此在进行此项 *** 作时要倍加小心 如果是开发应用程序 最好的办法是提供一个确认信息框确保用户不会意外删除记录
插入一条记录也很简单 Delphi为用户提供两种方法用来插入记录到现存数据库表中 一种方法是在当前记录指针所在的记录处插入记录 另一种方法是在数据库表的尾部插入记录 这两种方法是分别调用Insert方法和Append方法实现的 但是无论是调用Insert方法还是调用Append方法在具有索引的数据库表中插入记录 增加到索引表中的记录都将按照索引顺序写入到数据库表中 也就是说对于索引表 调用Insert和Append方法的效果是一样的 事实上 Append方法只适用于那些没有索引的表 这种没有索引的表并不十分有用因而通常不创建这种表 几乎任何情况下我们都是用Insert方法来插入记录
用户在插入记录时一般可以采用两种方式插入 逐步插入即首先建立一条空记录 然后再填充记录的各个字段 最后再将记录写回到磁盘 共分三个独立的 *** 作步骤 而使用InsertRecord方法便可以一次将插入记录的 *** 作完成
逐步插入方法
逐步插入方法分为三个明确的步骤 先调用TTable部件的Insert方法在TTable中创建一条新的空记录 然后填充该记录的各个字段 最后调用post方法把新记录写到磁盘上的实际数据库文件中 在填充并传送记录以前 考虑插入记录到表中的什么位置是毫无意义的 假设插入的表是有索引的 在调用post方法时 Delphi会自动地把插入的新记录按照索引顺序插入到表中的正确位置 如果插入的表中没有索引 那么新记录将插入到当前指针所在记录的后面
因此 采用逐步插入方法插入记录的程序代码一般如下形式
With Table do
begin
Insert{插入一条空白记录}
<填充该记录的各个字段>
post{将插入的记录写回到磁盘文件}
end
对于没有索引的数据库表 可以用Append方法替代Insert方法把新记录插入到表的尾部
调用InsertRecord插入记录
对于简单的应用程序 Delphi允许用户用一条语句插入一个新记录 而且这个新记录可以带有任意多个新字段值 InsertRecord方法把新记录中字段的赋值语句和psot方法调用组合进一条语句中
InsertRecord方法把记录的各个字段值组合成一个字段值数组作为它的唯一参数 在字段值数组中 可以为插入的记录的每个字段提供一个字段值 或从最左一列开始依次为任意多个字段赋值 也就是说用户可以从表的最左边一列起 把多个列的值同时传递给InsertRecord 直到所有字段都被赋值 用户也可以省略后面的字段 InsertRecord会用空值填充这些没有赋值的字段 用户还可以对那些明确希望用空值填充的字段传递保留字NIL来标明该字段为空
如我们希望在Customer DB表中插入一条记录 可以用下面的代码来实现
InsertRecord([ NIL NIL NIL])
在上面的程序代码中 我们只填充了四个字段 CustNo Company Add Add InsertRecord会自动将其它字段赋以空值
例 在这个例子中 我们在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
TForm = class(TForm)
DBGrid : TDBGrid
DBNavigator: TDBNavigator
Panel : TPanel
DataSource : TDataSource
Panel : TPanel
customerTable: TTable
BitBtn : TBitBtn
Label : TLabel
Label : TLabel
BitBtn : TBitBtn
BitBtn : TBitBtn
CustNoEdit: TEdit
CompEdit: TEdit
procedure FormCreate(Sender: TObject)
procedure BitBtn Click(Sender: TObject)
procedure BitBtn Click(Sender: TObject)
procedure FormActivate(Sender: TObject)
private
{ private declarations }
public
{ public declarations }
end
var
Form : TForm
implementation
{$R * DFM}
procedure TForm FormCreate(Sender: TObject)
begin
customerTable Open
end
procedure TForm BitBtn Click(Sender: TObject)
begin
If (Length(CustNoEdit text)= )and
(Length(CompEdit text)= )
then
MessageDlg( 没有输入新记录的字段值! mtError [mbCancel] )
else
with customerTable do
begin
IndexFieldNames:= CustNo
If FindKey([CustNoEdit text]) then
MessageDlg( 已经存在这条记录! mtError [mbCancel] )
else
InsertRecord([StrToInt(CustNoEdit text) CompEdit text nil])
CustNoEdit text:=
CompEdit text:=
end
end
procedure TForm BitBtn Click(Sender: TObject)
begin
If (Length(CustNoEdit text)= )and
(Length(CompEdit text)= )
then
MessageDlg( 没有输入删除的记录的字段值! mtError [mbCancel] )
else
with customerTable do
begin
IndexFieldNames:= CustNo
If FindKey([CustNoEdit text]) then
begin
If MessageDlg( 你确定要删除这条记录吗? mtConfirmation
[mbYes mbno] )=mrYes then Delete
end
else
MessageDlg( 没有你要删除的记录! mtError [mbCancel] )
CustNoEdit text:=
CompEdit text:=
end
end
procedure TForm FormActivate(Sender: TObject)
begin
CustNoEdit setfocus
end
end
输入数据的有效性验证
当用户向一个数据库表中插入新记录或修改原有记录时 我们必须确保用户输入的数据是有效的 为此Delphi通过三种不同的途径用来验证用户输入的数据是否有效
这三种途径是 基于数据库表的有效性验证 基于字段的有效性验证 基于记录的有效性验证
lishixinzhi/Article/program/Delphi/201311/25165
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)