数据修改
本章内容为增加、删除、修改数据库表中的记录。
开发数据库应用程序的主要目的,就是提供一种修改数据的方法。在第5章,课程展示了如何连接到一个Access数据库,如何显示数据库表中的数据,以及如何遍历浏览表中的记录。
在本章中,将会学习如何增加、删除和修改数据——通过db-aware/enabled组件对象中的某些属性、事件和方法。
首先,我们需要创建一个类似于前面章节中所创建的数据窗体。通过使用标准的组件集(DataSource、ADOTable和ADOConnection)来连接到Access数据库。这一次,我们将探索Authors表。回想一下,Authors表具有三个字段(列):authorName,Email和Web,且都为文本字段。在第一章中,我们已增加了一条“虚拟”记录。
创建一个新的Delphi项目,在默认窗体上放置所有的数据访问组件以及一个DBGrid和DBNavigator。使用Object Inspector关联这些组件,并将ADOTable1的TableName指向Authors表——这些实现连接的步骤你应该已经很熟悉了。使用ADOTable的Active属性在设计时激活连接;或在窗体的OnCreate/ OnClose这对事件句柄中处理,在运行时打开/关闭数据集。
用Delphi开发数据库应用程序的巨大优势之一便是TField对象的存在。如前几章所述,数据库字段可以是持久性的或是动态创建的。我们建议设置持久性(已知)的数据集字段列表——通过使用Object Inspector将这三个字段添加到列表中。并使用拖放(详见第5章),将数据感知控件DBEdits连接到数据库表中的特定字段。
Posting
当各组件关联后,同数据感知组如DBGrid一起使用的DBNavigator,能对表中的记录进行半自动化的修改、删除和增加操作。例如,假设你正在使用DBGrid浏览记录集,并开始在某些单元格重新键入文本(编辑基础字段的值),这时,该数据还没有被修改,直到POST方法被调用。(数据集的)Post方法在Delphi数据库应用程序中起着关键作用。
当数据集处于编辑(Edit)状态时,调用Post会修改当前的记录。点击DBNavigator的Post按钮(面板上的“√”按钮)时便会调用Post方法。你需要知道,当你移动到下一条记录时,Post会被隐式的调用——例如在DBGrid中编辑记录时,按向下(▶)键。
应用程序(显式或隐式)调用Post方法时产生的事件,通过Delphi可以抓取到;例如,(数据集的)BeforePost事件会在记录“修改”之前触发。在数据变化发布到数据库之前,应用程序可以用OnBeforePost来进行有效性检查。这种基于记录的验证,是非常有必要的——尤其对于那些需要判断输入值是否有效的字段。同时,可以用字段特有的OnValidate事件来验证有效性。调用字段编辑器,并选择相应的字段,在ObjectInspector中即可找到OnValidate。
Editing a record
为了能够对数据集返回的数据进行编辑,数据集必须处于编辑状态。数据感知控件(DBGrid、DBEdit)的AutoEdit属性默认是为True的,当用户一开始编辑控件中的值时,数据集状态就会从“浏览”变为“编辑”。当我们试图把一个已处于编辑状态的数据集置为编辑状态时,程序不会产生错误。
代码如下:
ADOTable1.Edit; //将数据集置于“编辑”状态
ADOTable1AuthorName.Value := 'Delphi Guide'; //将字符串‘Delphi Guide’赋值给AuthorName字段
ADOTable1.Post; //将修改后的数据发布到数据库;
一起看看上次调用所触发的一些事件:
ADOTable1BeforeEdit
DataSource1StateChange
DataSource1DataChange
ADOTable1AfterEdit
ADOTable1AuthorNameValidate
ADOTable1AuthorNameChange
DataSource1DataChange
DataSource1StateChange
ADOTable1BeforePost
DataSource1StateChange
ADOTable1AfterPost
Adding a new record
向表中添加一条新记录最简单的方法是单击DBNavigators的“插入(+)”按钮。调用Insert方法,会在表中添加并打开一个新的记录——DBGrid首列带星号标志的空行。其三个DBEdit组件都是空的,以便用户输入新的记录值。
同样,调用Insert也会触发一系列的相关事件。
下面为插入并发布新记录的相关示例代码:
with ADOTable1 do begin
Insert;
FieldByName('AuthorName').Value := 'ZarkoGajic';
FieldByName('Email').Value := 'gzarko@sf.hr';
FieldByName('Web').Value:= 'http://sf.hr';
Post;
end;
注: ADOTable组件具有InsertRecord方法,可用于在数据集创建一个新的空记录,填写字段的值,并将值发布到数据库中——所有这些操作只需一行代码。示例如下:
ADOTable1.InsertRecord('ZarkoGajic','gzarko@sf.hr','http://sf.hr');
"Undo" changes
在“编辑”(修改数据)或插入状态(添加一条新纪录)时,应用程序可以调用Cancel方法。 或点击DBNavigator上的“×”按钮。如果在编辑记录时调用,已连接的数据感知控件复原为原来的值;插入时调用空行会被“删除”。取消操作会使数据集返回到浏览状态。
Deleting a record
点击DBNavigator上的“-”按钮,将调用数据集的Delete方法,调用Delete方法后不需再调用Post。我们可以用BeforeDelete事件来试图防止用户从表中删除记录;当然,DBNavigator的ConfirmDelete属性也能防止用户意外删除记录。如果没有一个已连接到数据集的DBNavigator——也可在DBGrid上按Ctrl+ Delete来调用Delete方法。如果在执行Delete方法时发生错误,将会触发OnDeleteError事件。
下一章,我们将使用多种方法来修改数据集中的数据。我们只需知道,Delphi已经为我们提供了足够的属性、方法和事件,来确保我们有办法控制如何去处理数据。