Delphi实用教程 第8章 数据库编程 第8章 数据库编程
8.1数据库应用程序的构成 8.1.1 客户机/服务器体系结构 1. 客户机/服务器(Client/Server)模型 客户机/服务器(C/S)代表了软件实体(如进程、对象)之间相互作用时的一种最典型的模式和相互关系。在这种模式中,服务器实现了某种功能,客户机则以某种方式从服务器处获得这种功能。 客户机/服务器结构 第8章 数据库编程
8.1.1 客户机/服务器体系结构 服务器软件与客户机软件的功能分布见表。 客户机/服务器功能 第8章 数据库编程
8.1.1 客户机/服务器体系结构 2. SQL Server 2000 与Delphi的完美结合 微软SQL Server 2000作为大型的关系数据库管理系统 (RDBMS)提供了对数据库管理和开发的支持,它是一个基于客户机/服务器(C/S)模式的关系数据库管理系统,其C/S体系结构如图所示。 商业逻辑和向用户提供数据 进行数据库数据操作和管理 第8章 数据库编程
8.1.2 Delphi数据库应用程序 应用程序的组件构成 数据库应用程序在逻辑上通常由两部分构成: ● 是数据库访问链路 ● 是用户界面 ● 是数据库访问链路 ● 是用户界面 数据库应用程序的组件构成 第8章 数据库编程
8.1.2 Delphi数据库应用程序 (1)用户界面 用户界面用于将数据库中的数据显示出来,并提供一种操作 机制,使用户能够对数据库中的数据进行编辑和浏览操作。(2)数据模块 ●数据模块是Delphi中一个类似窗体(Form)的组件,它相 当于一个容器,用于放置数据库组件,如组件Table、 Query、Database、Session、StoredProc等,这些与数据库 相关组件均为不可视组件。 ●通过数据模块组件来组织数据库组件有二个主要的优点: ◆这些不可视组件不用直接放在窗体上了, 简化了窗体的设计。 ◆可以对数据库相关组件进行统一管理,共享相同的 内容。 ●数据模块体现了Delphi面向对象和组件重用的特性。 ●击主菜单的FileNewData Module命令可添加新的空白数 据模块 。 第8章 数据库编程
8.1.2 Delphi数据库应用程序 数据源组件是数据显示组件和数据集组件之间的中介。当使用 (3)数据源 数据模块时,数据源组件是数据模块的一部分,通过组件面 板的Data Access页中的组件进行数据源设计。 (4)数据集 数据集是数据库应用程序的核心。数据集组件保存了一系列从 底层的数据库取出的记录。这些记录的数据可以取自一个数据 表、一个数据表的若干个字段、多个数据表的若干字段。可通 过组件面板的BDE、ADO页中的组件进行设计。 第8章 数据库编程
8.1.2 Delphi数据库应用程序 不同类型的数据集采用不同的机制连接底层数据库。常见的 有BDE、ODBC及ADO等几种方式。 (5)连接部分 不同类型的数据集采用不同的机制连接底层数据库。常见的 有BDE、ODBC及ADO等几种方式。 数据存取机制 第8章 数据库编程
8.1.2 Delphi数据库应用程序 2. 数据库应用程序的层次划分 数据库应用程序的体系结构主要由两方面决定: ● 使用的数据库类型(即是本地数据库还是远程数据库) ● 同时访问数据库的用户数以及数据库中需要存储哪些类 型的信息。 (1)单层数据库应用程序 单层数据库应用程序中,应用程序和数据库共享同一个 文件系统,它们使用本地数据库或文件来存取数据。 单层数据库应用程序的结构 第8章 数据库编程
8.1.2 Delphi数据库应用程序 ( 2)两层数据库应用程序 在两层数据库应用程序中,客户程序提供用户界面, 通过BDE、ADO从远程数据库服务器数获取数据。 BDE方式下的两层数据库应用程序结构 ADO方式下的两层数据库应用程序结构 第8章 数据库编程
8.1.2 Delphi数据库应用程序 (3)多层数据库应用程序 在多层数据库应用程序中,客户程序、应用服务器和 远程数据库服务器通常分布在不同的机器上。客户程 序主要提供用户界面,它向应用服务器请求数据和申 请更新数据;再由应用服务器向远程数据库服务器请求数据 和申请更新数据。 第8章 数据库编程
8.1.3数据库应用程序的建立 Delphi数据库应用程序主要有两种方法: 直接在窗体中放入数据组件; 先创建数据模块,再对数据模块进行引用。 下面用两例来说明: 第8章 数据库编程
1.直接在窗体中放置数据访问组件法 (1)选择主菜单下的FileNewApplication,创建一个应用程序。 (2)从Data Access页上将一个数据源组件DataSource拖放到主窗体 上。数据源组件在组件面板上位置如图所示。 (3)从BDE页上将一个数据表组件Table拖放到主窗体上。数据表 组件在组件面板上位置如图所示。 数据源组件 数据源组件在组件面板上的位置 数据表组件在组件面板上的位置 数据源组件 第8章 数据库编程
1.直接在窗体中放置数据访问组件法 (4)从Data Control页上将一个表格显示组件DBGrid和一个数 据浏览组件DBNavigator拖放到主窗体上。DBGrid组件用 于显示数据表中的记录;DBNavigator组件用于对数据表进 行编辑和浏览。两个组件在组件面板的位置。 DBGrid组件 表格、导航组件在组件面板上的位置 DBNavigator组件 第8章 数据库编程
1.直接在窗体中放置数据访问组件法 (5)按表设置各组件对象的属性。运行后主窗体如图所示。 窗体和组件对象属性表 数据源 数据浏览 数据表 表格显示 程序界面(设置属性值后的状态) 第8章 数据库编程
2.使用数据模块创建 (1)选择主菜单下的FileNewApplication,创建一个应用程序。 (2)选择主菜单下的FileNewData Module,创建一个数据模块。 (3)向数据模块中添加一个数据源组件DataSource和一个数据表组件 Table,添加了这两个组件后的数据模块。 (4)向主窗体中添加一个表格显示组件DBGrid和一个数据浏览组件 DBNavigator。 第8章 数据库编程
2.使用数据模块创建 (5)保存数据模块单元为DMUStu,保存主窗体单元为FormMain。 (6)鼠标单击主窗体,选择主菜单下的FileUse Unit命令,选择 数据模块对应的单元文件,在本例中对应的单元文件为 DMUStu,如图所示,单击窗体中的OK按钮,使主窗体的单 元文件能够引用数据模块的单元文件。查看主窗体的单元文 件FormMain代码,会发现在实现部分增加了一条语句:uses DMUStu; 该语句由本步操作过程产生,表明主窗体引用了这 个数据模块。 第8章 数据库编程
2.使用数据模块创建 (7)按表设置各组件对象的属性。运行程序。 第8章 数据库编程
8.2数据源组件DataSource 数据源组件在数据集组件与数据显示/编辑组件之间提供了一个接口,起着两者之间通信的媒介作用。每一个数据显示/编辑组件通过数据源连接上数据集,取得要显示和操纵的数据。同样,数据集组件为了让它的数据被显示和操纵,必须连上数据源组件。另外,数据源组件在连接主/从结构的数据表时,也起着关键的作用。 第8章 数据库编程
8.2.1数据源组件的属性 1. AutoEdit属性 该属性决定是否允许数据显示/编辑组件修改数据,设置为True 时将允许数据显示/编辑组件修改数据(前提条件是该组件 DataSet属性对应的数据集组件ReadOnly属性设置为False)。 2. DataSet属性 标识该数据源组件正在连接哪一个数据集组件。 下面的代码在运行期改变数据源DS的数据集。 with DS do begin if (DataSet = DSet1) then DataSet := DSet2 else DataSet := DSet3; end; 3. Enabled属性 该属性决定DataSource是否生效。 4. State属性 State是只读属性,表示与该数据源相连接的数据集组件的状态。 第8章 数据库编程
8.2.2数据源的方法 1. Edit方法 Edit方法使数据源相联系的数据集进入编辑状态,也可通过修 改数据源的AutoEdit属性来实现该功能。 2. IsLinkedTo方法 函数原型:function IsLinkedTo(DataSet: TDataSet): Boolean; 该函数用来判断数据源是否与参数DataSet中指定的数据集相联系。 第8章 数据库编程
8.2.3数据源的常用事件 1. OnDataChange事件 当数据显示/编辑组件移动指针,或修改了字段中的数据时, 将触发该事件。另外,数据集中的Next或Prior方法也能触 发 OnDataChange事件。 2. OnUpdateData事件 当前的记录被更新时,将触发该事件。该事件在数据集的post 方法之前被调用,一般用于对数据在提交前进行附加的处理和 有效性检查。 3. OnStateChange事件 在数据集的状态改变时,将触发该事件。 第8章 数据库编程
8.3 数据集组件DataSet DataSet定义了一些关于数据集的基本属性、方法和事件,在此基础上,派生出Query、Table、StoreProc、ADOTable、ADOQuery、ADOStoreProc等组件。 有以下两种方法使用DataSet: 直接使用Delphi内建的DataSet子类,如Table、Query及StoreProc等。在程序中使用这些对象,就相当于打开了相对应的数据集。 通过继承DataSet,实现该类中所有的抽象方法。 第8章 数据库编程
8.3.1数据集的打开与关闭 有两种方法打开数据集: 在对象观察器设置Active属性为True,或在运行期间用代码设置Active:=True。 在应用程序运行期间,调用数据集的open方法。 关闭一个数据集也有两种方法: 在运行期中设置数据集的Active属性为False。 在应用程序运行期间,调用数据集的close方法。 第8章 数据库编程
8.3.2数据集状态及转换 数据集状态的属性的取值及含义 : 数据集的状态转换 : 第8章 数据库编程
8.3.3数据集的浏览 每个活动数据集有一个游标,指向数据集中当前行。当前行是指正在DBEdit、DBLabel、DBMemo等数据显示/编辑组件中所显示的记录或DBGrid中箭头所指的记录。可以通过移动游标来定位记录。 DataSet定义了BOF、EOF这两个布尔属性来提供有关游标的位置信息。 移动游标的方法 数据集的BOF和EOF 属性说明 第8章 数据库编程
8.3.3数据集的浏览 当执行了以下操作之一后,数据集的BOF属性为True。 l 首次打开数据集。 l 调用了First方法。 l 调用了Prior方法失败。 而执行了以下操作之一后,数据集的EOF属性为True。 l 打开一个空的数据集。 l 调用了Last方法。 l 调用了Next方法失败。 第8章 数据库编程
8.3.4对数据集进行增、删、改的操作 可以对数据集中的数据进行各种编辑操作,所对应的方法列于表中 with MyDataSet do begin Append; FieldValues[Field1_Name1]:= Field1_NewValue; FieldValues[Field2_Name2]:= Field2_NewValue; Post; end; 对数据集的修改受其CanModify属性影响。当CanModify为True时,表明数据集是可以修改的。另外,如果数据集是Table组件,只有ReadOnly属性为False,才能对其中的数据进行修改。 在数据集的最后添加一条记录 第8章 数据库编程
8.3.5数据集常用事件 数据集常用事件表 第8章 数据库编程
8.3.5数据集常用事件 由表可见,数据集响应的事件大致分为以下几大类: 1. Before+操作名 这一类事件在执行与操作名相应的操作之前被触发。 下面的代码在用户将修改的内容写回数据库中前,利用 BeforePost事件检查输入是否有效。该例检查TDBEdit,若为空 则不写回数据库。 // BeforePost事件代码 procedure TForm1.MyDataSetBeforePost(DataSet: TDataSet); begin if DBEdit1.Text = '' then Abort; end; 第8章 数据库编程
8.3.5数据集常用事件 2. After+操作名 该类事件在与操作名相应的操作完成后被触发,一般可用于报 告操作执行的结果。 当使用first、last、next、prior、moveby 等方法或数据浏览 组件DBNavigator时,在当前记录发生改变之前/之后触发 BeforeScroll事件和AfterScroll事件。 下面的代码利用AfterScroll事件,在状态条上显示当前记录号。 // AfterScroll事件代码 procedure TForm1. MyDataSetAfterScroll(DataSet: TDataSet); begin StatusBar1.panels[0].Text:='Record'+IntToStr(DataSet.RecNo) +‘Of'+IntToStr(DataSet.RecordCount); end; 第8章 数据库编程
8.3.5数据集常用事件 3. On+事件 该类事件与普通的OnClick事件相似,只是具体的触发条件不 同。如OnCalcFields事件在记录中的数据被修改时或者指针从 一条记录移动到另一条记录的时候被触发,该事件触发后, 将对数据集中的计算字段重新进行计算。 第8章 数据库编程
8.3.6数据集的字段 字段也是一种对象,在数据库编程时用得很多,使用也很灵活。字段对象都派生自TField类,是数据库应用中的基础。 字段对象完成如下功能: l 改变数据集中的字段值。 l 转换字段值的类型。 l 对用户输入的数据进行有效性检查。 l 定义字段如何显示或编辑。 l 根据数据集的OnCalcFields事件,计算字段的值。 访问记录中的数据,需要使用数据集的字段对象,如图所示。 第8章 数据库编程
8.3.6数据集的字段 1. 字段的访问方式 有两种方式可以访问当前记录的字段值。两种方式对于Query、 Table、StoredProc、ADOTable、ADOQuery、ADOStoredProc 等组件都有效,因为这些组件都是从TDataSet继承的。 (1)使用属性Fields[i]访问当前记录,Fields[i]是按照字段的顺序 来访问的。 访问这些属性的方法和处理其它对象一样。 Table1.Fields[0].DisplayLabel:=‘标识符’ (2)使用方法FieldByName按照字段的名字来访问。 对students表中的字段Name的访问: DataSet1.FieldByName(‘Name’).AsString:= Edit1.text; 把字段内的值显示出来: Edit1.text:= DataSet1.FieldByName(‘Name’).AsString; 第8章 数据库编程
8.3.6数据集的字段 2. 字段的属性 (1)显示控制属性 在数据表中,用户起的字段名一般都很简单、精炼,可以使用 Tfield 的显示控制属性改变字段的显示方式,获得友好的用户 界面。 例如,下列语句将按指定的宽度,显示students表的name字 段的汉字含义。 DBGridl.FieldByName(‘Name’).DisplayLabeL:=’ 姓名’; DBGridl.FieldByName(‘Name’).DisplayWidth:=8; TField的显示控制属性列于表中。 第8章 数据库编程
8.3.6数据集的字段 (2)约束条件 约束条件的设置是为了让输入的字段值合法,符合一定的条件。 字段对象可以使用用户自定义的约束条件进行检查。 约束条件相关属性表 第8章 数据库编程
8.3.6数据集的字段 3. 字段的事件 最常用的字段的事件列于表中。 第8章 数据库编程
8.3.6数据集的字段 4. 字段的方法 字段的方法列于表中。 第8章 数据库编程
8.3.6数据集的字段 ● 动态字段 5. 永久字段 数据集中的每一个字段创建一个TField对象,这些生成的 ● 动态字段 数据集中的每一个字段创建一个TField对象,这些生成的 TField对象可以通过代码控制某些属性。它对数据集的适应性 强,而控制它的属性比较麻烦,也不能增加新的计算型显示字段。 ● 永久字段 的选择和设置是在窗体或数据模块设计时完成的。它的字段容易控 制字段属性,也提供了界面以增加计算型字段。 第8章 数据库编程
8.3.6数据集的字段 ◆使用字段编辑器建立永久字段的步骤是: (1)在窗体上放入Table组件,设置该组件的属性DatabaseName 为student,TableName为students,Name为TabStu, Active为true。 (2)右击窗体上的TabStu,出现如图所示的快捷菜单,选择其中 的Fields Editor(字段编辑器)菜单项,将弹出如图所示 的表字段编辑窗口。 字段编辑器 Table的快捷菜单 字段编辑器的快捷菜单 字段编辑器及快捷菜单 第8章 数据库编程
8.3.6数据集的字段 (3)右击字段编辑器的空白处,出现快捷菜单,选择其中的Add all fields菜单项,所有字段立即出现在字段编辑器内。 字段列表 第8章 数据库编程
8.3.6数据集的字段 TForm1 = class(TForm) 永久性字段对象的访问形式: TabStu: TTable; TabStuStudentid: TStringField; TabStuName: TStringField; TabStuSex: TBooleanField; TabStuBirthday: TDateField; TabStuDepartmentid: TSmallintField; TabStuTotalscore: TFloatField; 永久性字段对象的访问形式: TabStuName.DisplayLabel:='姓名'; TabStuName.DisplayWidth:=8; Edit1.Text:= TabStuName.Value; TabStuName.Value:= Edit1.Text; 第8章 数据库编程
8.3.6数据集的字段 6. 字段的数据类型 由于各种数据库字段的数据类型不一,所以Delphi必须针对各个字段不同的数据类型,定义出各种不同数据类型的TField组件,这些组件都从TField组件继承下来的,所以它们所拥有的组件特性几乎都相同。 常用字段对象的类型 第8章 数据库编程
8.3.6数据集的字段 字段类型之间的主要区别在于:它们内部保留的以及它们和数据库表之间传递的数据类型不一样。字段对象还有一些类似于数据转化的属性。 第8章 数据库编程
8.3.6数据集的字段 一个字段可以用几种数据类型表示,转换规则如表所示。 以下两条赋值语句中的MyDataSet.Field[i]字段用2种类型表示: s:=MyDataSet.Field[i].AsString; //该字段以字符串表示 i: =MyDataSet.Field[i].AsInteger; //该字段以整数表示 注意:从字段对象中读取字段值时要将它赋给数据类型与之相匹配的变量。 常用类型转换规则举例 第8章 数据库编程
综合数据源、数据集及字段对象的示例 1)主窗体设计 设计时窗体 第8章 数据库编程
综合数据源、数据集及字段对象的示例 窗体和组件对象属性表 第8章 数据库编程
综合数据源、数据集及字段对象的示例 窗体和组件对象属性表 第8章 数据库编程
综合数据源、数据集及字段对象的示例 // 窗体的OnCreate事件处理代码,完成(1)的功能。 2)编写程序代码 procedure TFormObs.FormCreate(Sender: TObject); begin with TabStu do // 使用永久字段TabStuStudentid的属性DisplayLabel TabStuStudentid.DisplayLabel:='学号'; TabStuName.DisplayLabel:='姓名'; TabStuSex.DisplayLabel:='性别'; TabStuBirthday.DisplayLabel:='出生年月'; TabStuDepartmentid.DisplayLabel:='所在系编号'; TabStuTotalscore.DisplayLabel:='总分'; end; 第8章 数据库编程
综合数据源、数据集及字段对象的示例 // 永久字段TabStuSex的OnGetText事件处理代码,完成(2)的功能。 procedure TFormObs.TabStuSexGetText(Sender: TField; var Text: String; DisplayText: Boolean); // 参数Sender代表字段对象 begin if Sender.Value then Text:='男' // 若表中的某个记录的Sex字段值为true,则显示为“男” else Text:='女'; // 若记录的Sex字段值为true,则显示为“女” end; // 永久字段TabStuSex的OnSetText事件处理代码。 // 若由于录入错误,需修改性别时,用布尔值写入数据库中。 procedure TFormObs.TabStuSexSetText(Sender: TField; const Text: String); if Text='男' then Sender.Value:=true else Sender.Value:=false; 第8章 数据库编程
综合数据源、数据集及字段对象的示例 // GrdStu的OnDblClick事件处理代码 // 把最后一个记录的Name和Totalscore字段值分别写入两个编辑框中 procedure TFormObs.GrdStuDblClick(Sender: TObject); begin TabStu.DisableControls; try TabStu.First; // 指向第一条记录,对游标进行初始定位。 while not TabStu.Eof do// 在循环语句中,完成对每一条记录的处理。 // 可根据不同的应用,对记录进行处理。 // 本例中,把字段的值写入两个编辑框中 EdtName.Text:= TabStuName.Value; EdtTotal.Text:= TabStuTotalscore.AsString; TabStu.Next; // 指向下一条记录 end; finally TabStu.EnableControls; 第8章 数据库编程
综合数据源、数据集及字段对象的示例 // 数据源DSStu的OnDataChange事件处理代码。 procedure TFormObs.DSStuDataChange(Sender: TObject; Field: TField); var curStatus:string; // 在curStatus中存放表的当前状态,即“浏览”、“编辑”等 begin EdtName.Text:= TabStuName.Value; EdtTotal.Text:= TabStuTotalscore.AsString; end; // 数据源DSStu的OnStateChange事件处理代码,完成(3)的功能。 procedure TFormObs.DSStuStateChange(Sender: TObject); case TabStu.State of dsBrowse: curStatus:='浏览'; dsEdit: curStatus:='编辑'; dsInsert: curStatus:='插入'; else curStatus:='其它状态'; SBarObs.Panels[0].Text:=curStatus; // 将curStatus的值显示在工具栏上 第8章 数据库编程
综合数据源、数据集及字段对象的示例 // 按钮“开关数据集”的OnClick事件 procedure TFormObs.BtnOnOffClick(Sender: TObject); begin TabStu.Close; // 关闭数据集,触发TabStuBeforeClose事件 TabStu.Open; end; // 数据集的BeforeClose事件 procedure TFormObs.TabStuBeforeClose(DataSet: TDataSet); if (TabStu.State in [dsEdit, dsInsert]) then case MessageDlg('将修改的内容写回数据库中吗?', mtConfirmation, mbYesNoCancel, 0) of mrYes: TabStu.Post; // 将修改的内容写回数据库中 mrNo: TabStu.Cancel; // 放弃修改 mrCancel: Abort; // 不关闭数据集 第8章 数据库编程
综合数据源、数据集及字段对象的示例 4)运行程序 通过NagStu提交 点击“开关数据集”按钮,弹出了对话框 第8章 数据库编程
8.3.7数据库引擎BDE、ADO概述 数据库引擎BDE BDE是一个32位的数据库引擎,组件面板上的BDE页中的所有 数据集组件都是通过该引擎来访问物理实体上的数据库的。 BDE向用户提供了访问不同格式标准数据库的一致的API接 口。BDE是Delphi数据库功能的核心部分,是连接应用程序和 数据库的桥梁。 1)BDE的组成 BDE中主要包括的文件 第8章 数据库编程
8.3.7数据库引擎BDE、ADO概述 2)BDE的三种数据库访问方式 (1)通过BDE可以直接访问dBASE、Paradox、ASCII、FoxPro 以及Access数据库。 (2)一系列驱动程序(被称为SQL Links,只能在Delphi企业版 中使用)允许访问一些SQL服务器,包括Oracle、Sybase、 Microsoft、Infomix、InterBase与DB2服务器。 (3)ODBC连接。 通过BDE访问数据库的机制 第8章 数据库编程
8.3.7数据库引擎BDE、ADO概述 3)BDE Administrator的主要功能 在Windows中选择开始程序Borland Delph 7 BDE Administrator,即可运行BDE Administrator。 BDE Administrator主界面 第8章 数据库编程
8.3.7数据库引擎BDE、ADO概述 ◆BDE Administrator的主要功能: (1)别名管理 (2)驱动程序的管理 第8章 数据库编程
8.4 BDE组件 BDE页中有数据集组件Table、Query与StoredProc以及与Query组件相联系的UpdateSQL组件。Database与Session组件用于建立数据库连接,BatchMove组件用于复制数据;NestedTable组件主要用于将主从关系的数据嵌套在子数据表格中。BDEClientDataSet组件将ClientDataSet与BDE相关的数据访问组件结合起来。 NestedTable Database Query BatchMove UpdateSQL Table Session Database 第8章 数据库编程
8.4.1 Table组件 Table组件的主要属性 (1)DatabaseName属性 这个名称一般为BDE中定义的别名。对于BDE能够直接访问 的基于文件的数据库,这个名称也可以是一个路径名。 (2)TableName属性 TableName属性指明本组件实际对应的数据库中的表名。 (3)TableType属性 TableType属性用于设置本组件对应的数据表类型,默认值 为ttDefault,表明数据库表的类型由数据文件对应的扩展 名决定。 第8章 数据库编程
8.4.1 Table组件 Table组件的以下属性和方法用于表的创建和删除。 (4)Active属性 2. 表的建立与删除 Table组件的以下属性和方法用于表的创建和删除。 (1) FieldDefs属性 FieldDefs属性保存着数据集中字段定义的有关信息,可以用这个属 性来决定数据集中包含的字段、字段的名称、类型和长度, FieldDefs属性是属于TFieldDefs类的对象。AddFieldDef是类 TFieldDefs的对象的方法,用于定义字段,并且把该字段定义加入 到FieldDefs属性中。 (2)CreateTable方法和DeleteTable方法 CreateTable方法在程序运行时动态创建一个数据库,调用此方法前 需为DatabaseName、TableName、TableType及FieldDefs属性赋值。 DeleteTable方法删除一个数据表。 第8章 数据库编程
8.4.1 Table组件 【例】在D盘上创建一个数据库paradoxDB,表名为students.db, 包含一个字段名studentid,字符串类型, 长度为6,不可为空;一个字段 名totalscore,整型,可为空。 uses dbtables,db; var TabStu:TTable; {调用局部过程CreateSjTable完成表的具体创建工作} procedure CreateSjTable; begin TabStu:=TTable.Create(Form1); TabStu.close; with TabStu do begin Active := False; // 程序运行前需在D盘上建立一个名为stkgl的文 件夹,作为数据库名 DatabaseName := 'd:\paradoxDB'; TableName := 'students.db'; // 定义表名为students 第8章 数据库编程
8.4.1 Table组件 // 定义了students表中的两个字段studentid、totalscore with FieldDefs do begin Clear; // 字段studentid,字符串(6),不可为空; with AddFieldDef do begin Name := 'studentid'; DataType := ftString; Size := 6; Required := True; end; // 字段名totalscore,整型 Name := 'totalscore'; DataType := ftInteger; TabStu.CreateTable; // 调用Table的CreateTable方法,实际创建一个数据表。 TabStu.Free; // 最后,释放TabStu对象。 第8章 数据库编程
8.4.1 Table组件 Table对表中的记录进行增加、修改、删除的方法,均继承自 3. 表记录的增加、修改、删除 Table对表中的记录进行增加、修改、删除的方法,均继承自 TdataSet,请参见8.3.3节。 【例】建立一个应用程序,对students中的记录进行增加、 修改、删除等操作。这里,使用永久字段,请参照8.3.6节 有关永久字段中的字段编辑器建立永久字段的方法说明。 (1) 在窗体上添加一个Panel组件,并在面板中放入10个 SpeedButton组件,按图设置它们的Caption属性值。 (2) 将所有字段拖入窗体中,如图所示。 第8章 数据库编程
8.4.1 Table组件 (3) 添加事件处理程序。双击“第一条记录”按钮,为该按钮添加事 件处理程序,如下: procedure TForm1.SpeedButton1Click(Sender: Object); begin TabStu.First; end; 同样,利用Prior,Next,Last,Delete,Edit,Post,Cancel, Refresh等方法可为其它按钮添加事件处理程序。 第8章 数据库编程
8.4.1 Table组件 1)SetKey/GotoKey方法 4. 数据检索 的步骤如下: (1)调用SetKey方法,把要查找的Table组件置成查找模式。 (2)把查找值送进被查找的字段的查找缓冲区中。 (3)调用Table组件的GotoKey方法,测试该方法的返回值判 断查找是否成功。如果查找成功,GotoKey返回一个True值,并 且表中的记录指针指向查找到的记录。如果查找失败,GotoKey 方法返回False值,表中的记录指针不变化。 第8章 数据库编程
8.4.1 Table组件 【例】通过SetKey/GotoKey方法查询表中的数据。 程序功能是: 根据姓名查询表students,并将该学生的总分显示在面板PanTotal上。 (1) 所用的组件及其属性列于表中,程序主界面如图所示。 窗体和组件对象属性表 程序界面(设计时) 第8章 数据库编程
8.4.1 Table组件 (2) 编写代码 procedure TFormFind.BtnFindClick(Sender: TObject); // 按钮BtnFind的OnClick事件代码 begin with TabStu do IndexFieldNames:='Name'; //为查找关键字建立索引 // 以下是应用SetKey/GotoKey,查找记录的三个步骤 Setkey;//设定查找关键字 FieldByName('Name').Value:=EdtName.Text; // 通过FieldByName设置查找值 if GotoKey then // GotoKey返回值是Boolean类型,表明了是否找到所需的记录 {显示查找信息} panTotal.Caption:= '总分为'+FieldByName('totalscore').AsString; ShowMessage('查找成功'); end else panTotal.Caption:= '未查找到'; ShowMessage('查找失败'); end; 第8章 数据库编程
8.4.1 Table组件 (3) 说明 “对于非SQL表格,需在表格打开之前建立好索引”,这一点 很重要,在Paradox中建立索引的步骤是: l 打开Database Desktop选择主菜单 ToolsUtilitiesRestructure进入“Select file” 对话框。如图所示。 “Select file”对话框 第8章 数据库编程
8.4.1 Table组件 l 在Alias下拉列表框中选择student;然后在列出的 student数据库表中选择students.db;点击“打开”按钮, 进入“Restructure Paradox 7 Table:student.db”对话 框。如图所示。 “Restructure”对话框 第8章 数据库编程
8.4.1 Table组件 l 在Table Properties下拉列表框中选择Secondary Indexes,点击Define按钮,打开Define Secondary Index对话框,如图。在对话框左边的Fields列表框中选 择Name;点击按钮后,在对话框右边的Indexed Fields列 表框中出现刚才所选的Name字段;点击OK按钮。 Define Secondary Index对话框 第8章 数据库编程
8.4.1 Table组件 l 进入Save Index As对话框,为所建立的索引命名,如图。 在Index Name输入框中输入ByName;点击OK按钮返回 Restructure Paradox 7 Table:students.db对话框,点 击Save按钮,关闭Database Desktop。至此,即为Name字 段建立了索引。 Save Index As对话框 第8章 数据库编程
8.4.1 Table组件 2)FindKey方法 FindKey函数原型为: FindKey(const KeyValues: array of const): Boolean; 可按Table1.FindKey([‘990203,王月’])形式使用,其中的 “990203”、“王月”为字段值。 第8章 数据库编程
即为通过FindNearest方法查询。 8.4.1 Table组件 3)GotoNearest/FindNearest方法 GotoNearest和FindNearest两种方法进行不精确查找。 下面的过程是通过GotoNearest方法和FindNearest方法查询数 据库中的数据。 procedure Nearest1; begin with TabStu do IndexFieldNames:='Name'; Setkey; FieldByName('Name').Value:= edtName.Text; GotoNearest; …… end; 如果把上面程序在begin和end之间部分替换成: IndexFieldNames:='Name'; FindNearest([edtName.Text]); 即为通过FindNearest方法查询。 第8章 数据库编程
8.4.1 Table组件 4)设置检索范围 有两种方法可以实现显示使用Table时部分数据: ● 一种是数据集DataSet的过滤。 ● 一种是设置范围。 设置范围是通过给索引字段设置起始条件和结束条件来完成 的,过程如下: ● 使用SetRangeStart方法设置开始范围。 ● 使用SetRangeEnd方法设置结束范围。 ● 使用ApplyRange方法开始执行数据筛选操作。 ● 使用CancelRange方法取消范围设置。 第8章 数据库编程
8.4.1 Table组件 【例】给Name字段设置开始范围和结束范围,在GrdStu中显示符 合条件的记录,然后调用CancelRange取消范围设置,显示所有 记录。 procedure SetRange; //“设置范围”过程 begin with TabStu do IndexFieldNames:='Name'; // 下面的两行语句,设置查询字段的起始条件。 // 第2条语句把Edit1.text值作为Name字段的起始值。 SetRangeStart; FieldByname('Name').AsString:= Edit1.text; // 下面的两行语句,设置查询字段的终止条件。 // 第2条语句把Edit2.text值作为Name字段的终止值。 SetRangeEnd; FieldByname('Name').AsString:= Edit2.text; ApplyRange; end; 第8章 数据库编程
8.4.1 Table组件 5. 索引 1)建立、删除表内索引 ● AddIndex方法建立一个新的索引,建立时需指定索引名称和 索引字段; Procedure AddIndex(const Name, Fields: String; Options: TIndexOptions, const DescFields:String=''); ● DeleteIndex方法则删除索引。这两个方法的调用形式如下: procedure DeleteIndex(const Name: String); 第8章 数据库编程
8.4.1 Table组件 2)查询表内索引 在打开表之前,要想知道哪些索引已被设置,可以使用 IndexDefs属性。 3)指定当前使用的索引 使用属性IndexName和IndexFieldNames指定表内数据的显示顺 序,注意这两个属性是相排斥的。IndexName可以设置一个字段, 而IndexFiledNames可以设置多个索引字段,各个索引字段之间 用分号隔开。对于dBASE和Paradox的数据表,这些索引字段必须 存在于索引文件中;对于SQL服务器的表,则相当于增加了 Orderby子句。 第8章 数据库编程
8.4.1 Table组件 6. 主/从结构数据表格 通常,需要将数据与表格联系起来,这些表格具有一对多的关系即对于主表格的某个记录来说,在从表格中有多个记录与之对应。 两个表中意义相同的字段建立了两表间的联系。这两个表中相同的字段分别称为两表中的关联字段。在从表中的关联字段必须是从表中的索引字段。 【例】使用向导建立一个主/从结构数据表格。在student数据库 的students与grades表之间,建立一个主/从结构数据表格,关 联字段是studentid。步骤如下: 第8章 数据库编程
8.4.1 Table组件 (1)选择窗体种类和数据集种类。选择主菜单Database FormWizard,弹出如图对话框,在其中选择窗 体类型和数据集类型,然后单击Next按钮。 第8章 数据库编程
8.4.1 Table组件 (2)选择数据表。系统将弹出如图所示的选择指定表的对话框。 在Driver Or Alias Name组合列表框中选择驱动器名 (如e:),在Directories中选择路径,在Table Name文本 编辑框下面的列表框中选择表名(如students.db),单击 Next按钮。 第8章 数据库编程
8.4.1 Table组件 (3)在所弹出的对话框中选择需在目标窗体上显示的列,如图 所示。本例中将选择除Birthday字段外的所有字段,单 击Next按钮。 选择选定字段 选择所有字段 取消选定字段 取消所有字段 第8章 数据库编程
8.4.1 Table组件 (4)在所弹出的对话框中选择字段显示方式,如图所示。字段显 示方式有3种:Horizontally(水平方式)、Vertically(垂 直方式)、In a grid(表格方式)。本例中选择水平方式, 单击Next按钮。 第8章 数据库编程
8.4.1 Table组件 (5)选择“grades.db”作为从数据表,选择方法与(2)相同, 如图。 第8章 数据库编程
8.4.1 Table组件 (6)选择从数据表字段和显示方式,选择方法与第(3)、(4) 步相同。本例中选择grades表的所有字段,单击Next按钮, 如图所示。再选择以表格方式显示,单击Next按钮。 第8章 数据库编程
8.4.1 Table组件 (7)在主/从数据表中各选择一个字段,建立主/从数据表的关联。 本例在“Detail Fields”框中选择studentid;在“Master Fields”框中选择studentid,建立起表间的关联;按, 单击Next按钮。 第8章 数据库编程
8.4.1 Table组件 (8)系统将弹出如图所示的对话框,完成生成窗体前的最后设置。 在这个对话框中,有如下内容供选择: ● Generate a main form:设定生成的表数据显示窗体 是否为主窗体。 ● Form Only:只生成窗体。 ● Form and Data Module:生成窗体和放置数据库组件 的数据模块。 第8章 数据库编程
8.4.1 Table组件 (9)设置Table1和Table2的Active属性为true。由FormWizard生成的 students/grades表对应的数据显示窗体 第8章 数据库编程
8.4.1 Table组件 【例】手工实现students/grades主从表。 为了手工实现与自动生成的具有相同的主从表关系,在窗体或数据模 块上放置两个表格组件,将它们与相同的数据库相连,并将每个组件 与一个数据表格相连。 (1)在窗体上添加两个数据表TsbStu、TabGrad,为每个数据表格添加 一个数据源组件DSStu、DSGrad,并将从表TabGrad的主数据源属 性MasterSource设置为与第一个表相连的数据源。 (2)选中从表TabGrad,在对象观察器中点击从表MasterFields属性右 边的 按钮,进入设置关联字段的编辑器 (FieldLinkDesigner),通过该编辑器将从表中的关联字段与主表 的关联字段(MasterField)联系起来。 第8章 数据库编程
8.4.1 Table组件 设计好的界面和所用组件及其属性如表所示。 程序界面 窗体和组件对象属性表 第8章 数据库编程
8.4.1 Table组件 1)字段编辑器的拖放功能 7. 字段编辑器 字段编辑器拖放功能就可实现一个窗口范围就能显示出所有 的字段。 字段编辑器拖放功能就可实现一个窗口范围就能显示出所有 的字段。 2)利用字段编辑器定义计算字段 3)利用字段编辑器定义查看字段(Lookup字段) 主要用于某个表的字段希望引用另外一个表的其他字段。 第8章 数据库编程
8.4.1 Table组件 【例】本例为Courses表添加计算字段“均学时”;为Students表添 加查看字段院系名称department。 (1)按图在主窗体中添加组件,按表设置组件属性。 程序界面 窗体和组件对象属性表 第8章 数据库编程
8.4.1 Table组件 l 使用字段编辑器,把TabCour中的所有字段添加为永久字段。 (2) 定义计算字段 l 打开字段编辑器TabCour的快捷菜单,选择NewField菜单项, 系统将弹出一个NewField(新字段)窗口。在Name输入框内 输入“Jxs”,在Type中选择Smallint,在FieldType区域选 中Calculated,然后单击OK按钮,如图所示。 第8章 数据库编程
8.4.1 Table组件 l 编写TabCour的OnCalcFields事件代码: procedure TForm1.TabCourCalcFields(DataSet: TDataSet); begin TabCourJxs.Value:=TabCourHours. ValuedivTabCourScore.Value; end; (3)定义查看字段 l 使用字段编辑器,把TabStu中的所有字段添加为永久字段。 l 打开TabStu字段编辑器的快捷菜单,选择New Field功能,添加一个 Lookup字段。在Field properties区域,在Name输入框内输入“Dep”; 在Type中选择String。在FieldType区域选中Lookup。在Lookup definition区域,在Dataset中选择TabCode;在Key Fields中选择 Departmentid;在Lookup Keys中选择Departmentid;在Result Field中 选择Department。然后单击OK按钮。 第8章 数据库编程
8.4.1 Table组件 定义查看字段—Dep(院系名称) (4)执行程序。观察计算字段Jxs的结果。 第8章 数据库编程
8.4.2 Query组件 Query组件的属性和方法 1)SQL属性 SQL属性是Query组件最重要的属性之一,它是存放SQL语句的地方。在代码中让Query组件实现查询功能,可按以下步骤进行: (1)调用Query组件的Close方法关闭本组件。 (2)使用Query.SQL的Clear方法清除原来的SQL语句。 (3)调用SQL属性的Add方法添加新的SQL语句。 (4)调用Query组件Open或ExecSQL方法执行新的SQL语句。 下面的示例说明了上面介绍的操作步骤。 Queryl.Close; Queryl.SQL.Clear; // 清除SQL属性中的SQL命令 Queryl.SQL.Add('select * from customer'); // 加入SQL命令 Query1.Open或Queryl.ExecSQL; // 执行加入的SQL命令 第8章 数据库编程
8.4.2 Query组件 2)Active属性 Query组件可以通过将Active属性设为True来运行SQL语句, 不过一般通过ExecSQL方法来运行SQL语句。如果Query组 件SQL语句有结果集,则也可通过Open方法运行SQL语句。 3)RequestLive属性 RequestLive属性也是Query组件非常重要的属性,该属性决定 了用户是否能够对结果集中的记录进行修改,默认值为False。 第8章 数据库编程
8.4.2 Query组件 ◆如果要返回的结果集可以被修改,必须满足两个条件: 一是该属性值应设为True;二是使用BDE内置的SQL必须符 合下列条件,才能返回一个可修改结果集: l 只含有一个数据表,没有连接Join。 l Select子句不含有DISTINCT,也没有使用计算字段。 l 没有ORDER BY子句。 l 没有使用GROUP BY子句,也没有SUM及AVG等聚集函数。 l WHERE子句只由列名及常数的比较组成,比较运算符可以是 >,<,>=,<=,=,<>,不可以有LIKE及IS运算符。 对于SQL服务器上数据表的查询,必须符合下列条件,才能返回可 修改结果集: l 只含有一个数据表。 l 没有使用SUM及AVG等聚集函数。 l 如果数据表在Sybase服务器上,它还必须有一个惟一索引。 第8章 数据库编程
8.4.2 Query组件 4)Prepare和UnPrepare方法 ● Prepare方法可以提高Query在远程服务器上和BDE上的优 先级,从而显著提高应用程序的性能。在更改SQL命令过 程时,Query将自动关闭或自动转成未准备状态。 ● UnPrepare方法是与Prepare相逆的过程,其作用是释放分 配给先前已准备好的查询资源。 5)Open和ExecSQL方法 Query组件分别采用Open和ExecSQL方法执行这两类SQL语句。 可以都使用Open方法来执行所有的SQL程序。 第8章 数据库编程
8.4.2 Query组件 2. 实现动态查询 Query组件的动态SQL语句是指带有参数的SQL命令,这些参数的值在运行前不能事先确定,只能在运行过程中动态地确定,而且在程序运行过程中这些参数的值是可变的,即可以动态地赋值。 例如下面的语句就是一条动态SQL语句: select * from employee where LastName=:LAST; 程序为参数赋值,有下面两种方法可选用: 方法1: 根据参数在SQL语句中出现的顺序,设置Query组件的Params属性值。 方法2: 直接根据SQL语句中各参数的名称及调用方法ParamByName来为各参数赋值。 第8章 数据库编程
8.4.3 StoredProc组件 存储过程组件 使用StoredProc组件的一般步骤如下: (1) 设置属性DatabaseName,为StoredProc组件指定要访问 的数据库名。 (2)设置属性StoredProcName,指定存储过程的名称(可通过 下拉菜单选择)。 (3) 为存储过程指定参数值。存储过程在运行时往往需要一些 参数,存储过程的参数有四种类型,分别为: l 输入参数,由客户程序向存储过程传递值。 l 输出参数,由存储过程向客户程序返回结果。 l 输入/输出参数,既可以向存储过程提供参数值,又 可从存储过程返回值。 l 状态参数,由存储过程向客户程序返回错误信息。 第8章 数据库编程
8.4.3 StoredProc组件 (1) Params属性 设置输入和输出的参数。 (2) ParamBindMode属性 ParamBindMode指定了Params编辑器中的参数和存储过程 中 要求的参数的对应方式,它有下面两种设置: ● pbByName:通过参数名称的对应关系进行匹配。 ● pbByNumber:将指定的第一个参数和存储过程的第一 个参数相匹配,第二个参数和存储过程的第二个参数相 匹配,依此类推。 (3) Prepare方法 和Query一样,如果有输入参数的设置,则必须用Prepare方 法使组件处于预备执行状态。 第8章 数据库编程
8.4.3 StoredProc组件 (4) ExecProc方法 可以通过调用ExecProc方法执行存储过程,如果该存储过程有 返回值,程序可以通过ParamByName方法由输出参数获得返回 信息。 例如: 使用StoreProc组件调用EMPLOYEE中的DEPT_BUDGET存储过 程的代码: StoredProc1.ParamByName('DNO').AsString:=edit1.Text; StoredProc1.ExecProc; edit1.Text:=StoredProc1.ParamByName('TOT').AsString; //由输出参数'TOT'获得返回信息 第8章 数据库编程
8.4.4 DataBase组件 Database组件是为开发客户/服务器数据库应用程序时,设置登录数据库的有关参数而设置的。 可建立与数据库的永久性连接。 可建立应用程序级别的数据库别名。 可实现事务管理。 可进行服务器登录验证,有更高的安全性。 Database组件的常用方法 第8章 数据库编程
8.4.4 DataBase组件 建立与数据库的永久性连接 在数据模块或者窗体内定义的TDatabase对象,建立了永久连接永久连接具有管理事务的能力,可以创建BDE别名,响应服务器注册的onLogin事件。在复杂的C/S环境中,必须使用永久连接,以增强C/S应用程序的控制能力。 Database组件有: DatabaseName属性 要打开的数据库 Connected属性 控制开关数据库 KeepConnection属性 数据库是否一直连接 DataSets属性 列出了目前打开的所有数据集 DataSetCount属性 列出了打开的个数 CloseDataSets 关闭所有的数据集 Open方法 连接数据库 Close方法 关闭数据库 第8章 数据库编程
8.4.4 DataBase组件 2. 建立应用程序级别的数据库别名 可以使用Database建立别名。但是用该方法建立的别名,在程序终止运行后,别名就消失了,它建立的别名不能被保存到配置文件中。 建立别名的方法是: 选中Database组件单击鼠标右键弹出快捷菜单选择其中 的Database Editor菜单项在界面的Database Name选择框中 输入新建的别名再选择Driver Name。 配置程序级别的数据库别名 第8章 数据库编程
8.4.4 DataBase组件 3. 实现事务管理 事务控制的语句主要有: (1)Begin Transaction 事务开始,在用户程序中的一个事务开始之处嵌入此语句以 表示事务的开始。 (2)Commit Transaction 提交一个事务,在事务结束时提交事务中所有操作,使得对 数据库中的所有数据修改生效,此后数据的修改就无法恢复 了,此语句往往用于事务正常结束。 (3)Rollback Transaction 回滚一个事务至事务的开始,此语句往往用于事务执行失败 后,返回起点重新执行。 第8章 数据库编程
8.4.4 DataBase组件 数据库事务提交的程序段的一般模式: //按钮组件ApplyButton的OnClick事件代码 procedure Tforml.ApplyButtonClick(Sender:TObject); begin with CustomerQuery do // CustomerQuery为数据集组件 Databasel.StartTransaction; try ApplyUpdates; // 应用更新 Database1.Commit; except Database1.Rollback; // 如果产生异常,回滚将撤消对数据的修改。 raise; end; CommitUpdates; // 没有产生异常则提交更新 第8章 数据库编程
8.4.4 DataBase组件 Database组件与服务器登录验证操作相关的属性事件: 4. 服务器登录验证 LoginPrompt属性 Params属性 指明数据库连接的参数,如路径、服务器名、用户名及密码等。 OnLogin事件 发生在应用程序与数据库建立连接的时候。 第8章 数据库编程
8.4.4 DataBase组件 程序里设置用户名和口令有两种方法: (1)将用户名和口令信息写在属性Params参数表中 先将属性LoginPrompt设置为False,然后在代码编辑器内加 入以下两句(以LocalInterbase服务器为例): USERNAME=SYSDBA PASSWORD=masterkey (2)使用OnLogin事件 将LoginPrompt属性设置为True,然后在OnLogin事件中填写 以下代码: LoginParams.values['USERNAME']:='SYSDBA'; LoginParams.values['PASSWORD']:='masterkey'; 第8章 数据库编程
8.4.5 UpDateSQL组件 缓冲技术与UpDateSQL组件 缓冲技术就是从服务器检索数据,保存至缓冲区内,然后在本机编辑,最后将更新后的数据送回至服务器。使用缓冲技术,可以减少网络负荷,减少数据库事务处理次数和服务器资源的锁定。 UpdateSQL组件用来配合具有缓冲能力的数据集组件,将更新的数据刷新到服务器端。 使用缓冲的好处还在于能够将某些只读的数据集变得可编辑。 第8章 数据库编程
8.4.5 UpDateSQL组件 2. 使用UpdateSQL 使用UpdateSQL组件的一般步骤是: (2)设置UpdateSQL组件的属性,主要是InsertSQL,DeleteSQL 及ModifySQL,表示当把缓冲区内的更新数据送回至服务器 时,在服务器上所进行的插入、删除、修改等操作。 如DeleteSQL语句: delete from "students.db" where Studentid = :OLD_Studentid 如ModifySQL语句: update "students.db" set Departmentid = :Departmentid, Totalscore = :Totalscore where Studentid = :OLD_Studentid 表示使用旧值 第8章 数据库编程
8.4.5 UpDateSQL组件 UpdateSQL组件主要通过以上介绍的三组SQL语句来工作。 (2)设置数据集组件的UpdateObject属性,指定到UpSQL组件上。 (3)在UpSQL组件上双击鼠标,弹出如图所示的UpdateSQL编辑器 界面,在编辑器中进行以下的编辑工作: 第8章 数据库编程
表示把“Key Fields”和“Update Fields”列表中的字段恢复为默认值 8.4.5 UpDateSQL组件 使用向导,建立三组SQL语句的过程: 表示把“Key Fields”和“Update Fields”列表中的字段恢复为默认值 1。选择需要更新的表名 2。获取所选表的字段 4。生成三组SQL语句 3。设置关键字段。 表中有带空格的字段名 UpdateSQL编辑器 第8章 数据库编程
8.4.5 UpDateSQL组件 (4)将缓冲区内的数据更新到服务器的数据库。有两种更新数 据到数据库的方法: (4)将缓冲区内的数据更新到服务器的数据库。有两种更新数 据到数据库的方法: ①使用TDatabase的方法ApplyUpdates ②使用数据集的ApplyUpdate方法。 与缓冲区操作有关的数据集方法 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 1. 程序完成的功能 (1) 直接用SQL语句对数据库student进行查询。用户在多行文` 本框中输入SQL查询命令,当点击“执行SQL语句”单选按钮 后,在表格显示组件中显示相应的查询结果。在此,使用 了Query组件。在程序运行时,通过对Query组件的SQL属性 进行设定,使程序能对数据库student中的表完成不同的查 询功能。 (2) 程序调用EMPLOYEE中的DEPT_BUDGET存储过程,查询该部门的 预算。当点击“执行存储过程DEP”单选按钮后,弹出输入对 话框,用户输入要查询的部门号后,程序调用DEPT_BUDGET 存储过程,查询该部门的预算。该存储过程有一个输入参数 部门号(‘DNO’)和输出参数(‘TOT’)。在“执行存储过程 Budget”单选按钮的OnClick事件代码中,调用存储过程。 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 (3) 使用Query组件Qrystudents,在表格显示组件GrdStu中所显 示的表Students中的数据为只读数据。在此,使用 UpdateSQL组件,利用缓冲区方式对Student数据库的 Students表中的记录进行操作。完成如下功能: ● 点击“使用缓冲”单选按钮,将缓冲区中的数据写到数据库。 ● 双击表格显示GrdStu组件,刷新显示。 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 2. 程序主界面 程序界面 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 窗体和组件对象属性表 窗体和组件对象属性表 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 窗体和组件对象属性表 窗体和组件对象属性表 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 3. 程序代码 // 单选按钮RBSP的OnCreate事件,对存储过程进行的处理。 procedure TFormSQLSP.RBSPClick(Sender: TObject); var InpDNO: string; begin InpDNO:= InputBox('执行存储过程DEPT_BUDGET', '输入部门号:', '-1'); SPBUDGET.ParamByName('DNO').Value:=InpDNO;// 对输入参数DNO赋值 SPBUDGET.ExecProc; // 执行存储过程 // 通过ParamByName方法,获得输出参数'TOT'值 MessageDlg(InpDNO+'部门的预算为:' +SPBUDGET.ParamByName('TOT').AsString, mtInformation,[mbOk], 0); RBSP.Checked:=false; end; 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 {多行文本框MemInpSQL的OnDblClick事件代码。当双击多行文本框时,清空它,为输入SQL语句做准备} procedure TFormSQLSP.MemInpSQLDblClick(Sender: TObject); begin MemInpSQL.Clear; MemInpSQL.SetFocus; end; // 单选按钮RBExeSQL的OnClick事件代码。对SQL查询进行的处理。 procedure TFormSQLSP.RBExeSQLClick(Sender: TObject); DSStu.DataSet:=QryStu; QryStu.Close; QryStu.SQL.Clear; {把MemInpSQL中输入的SQL查询命令,写入QryStu组件的SQL属性} QryStu.SQL.Add(MemInpSQL.text); QryStu.Open; RBExeSQL.Checked:=false; 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 // 使用Database的方法ApplyUpdates将数据更新到数据库。 procedure TFormSQLSP.RBBufClick(Sender: TObject); begin MemInpSQL.Lines.Clear; MemInpSQL.Lines.Add('select * from students'); DSStu.DataSet:=QryStudents; QryStudents.Open; QryStudents.Database.ApplyUpdates([QryStudents]); RBBuf.Checked:=false; end; // GrdStu组件的OnDblClick事件代码。刷新显示。 procedure TFormSQLSP.GrdStuDblClick(Sender: TObject); QryStudents.Close; 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 4. 运行程序 (1) 执行SQL语句 l 在MemInpSQL多行文本框中输入“select * from students”语句, 将在表 格显示GrdStu中显示出表students。 l 在Memo1中输入“select * from students where Name like ”王%“” 语句,将在GrdStu显示出表students中Name字段以“王”开头的所 有记录。 第8章 数据库编程
综合使用Query、StoreProc、Database及UpdateSQL组件 (2) 使用缓冲 l 修改“Departmentid”和“Totalscore”这两个字段的值后,使用Nag 组件的 按钮,提交所做修改,再双击Nag组件,所有被修改 的值不见了,又恢复为原来的值。这是由于要将缓冲区内的数据 写到数据库中,必 须使用UpdateSQL的方法。 l 修改“Departmentid”和“Totalscore”这两个字段的值后,点击“使 用缓冲”按钮,再双击表格显示GrdStu组件,刷新显示,会发 现字段值已经被修改了。 l 修改除“Departmentid”、“Totalscore”外的其它字段值,点击“ 使用缓冲”按钮,再双击表格显示GrdStu组件,刷新显示,将 会发现所有被修改的值不见了,这是由于只选择“Departmentid” 和“Totalscore”作为可被修改的字段,其余字段 仍 然是只读。 第8章 数据库编程
8.4.6其它BDE组件 BatchMove组件 BatchMove组件可以从数据集中成批地拷贝、删除、更新、 添加数据到另外一个表中。经常被用来将桌面数据库的数据 升级到SQL服务器上,或者保存查询后的数据用于分析。使 用BatchMove组件的步骤如下: (1)设置数据源属性Source,指向一个DataSet,可以是TTable、 TQuery等。 (2)设置属性Destination,指向一个目标数据表TTable。 (3)指定数据操作的方式属性Mode,最常用的是batCopy,含 义是将数据源的数据拷贝到目标数据库。如果目标数据库 不存在,则创建;否则改写数据库。 (4)设置其他属性,之后执行方法Execute。 第8章 数据库编程
8.4.6其它BDE组件 ◆在查询过程中,经常要把查询的数据保存起来,以便用于分析。下面编制Tbutton的OnClick事件,把查询的数据保存到指定文件中,程序段如下: procedure TForm1.Button1Click(Sender: TObject); begin {通过“另存为”对话框指定目标文件名} if SaveDialog1.Execute then Table1.TableName := SaveDialog1.FileName; with BatchMove1 do //使用BatchMove组件的4步骤 Source := Query1; Destination := Table1; Mode := batCopy; Execute; end; 第8章 数据库编程
8.4.6其它BDE组件 2. Session组件 Database。 ● Session组件主要用来管理数据库Database对象的连接和 ● Session组件连接了数据库引擎BDE和应用程序内的 Database。 ● Session组件主要用来管理数据库Database对象的连接和 关闭,检索BDE信息,管理Paradox数据表的多用户控制 以及Paradox和dBASE表的口令。 3. NestedTable组件 通过NestedTable组件可以访问嵌套数据集中的数据。NestedTable 组件从BDEDataSet组件继承了BDE的功能,所以可使用BDE访问嵌套表格中的数据。 第8章 数据库编程
8.5 ADO组件 ADO是微软公司面向各种数据的高层接口,这种层次接口被称为OLE DB。OLE DB访问速度快,可访问数据类型丰富,包括关系型与非关系型数据库、电子邮件与文件系统、文本与图片以及客户事务对象等。ADO组件编写的程序,可脱离Borland的BDE,而原有的数据显示/编辑组件(如DBGrid与DBEdit)可直接使用ADO组件。 ADO组件位于组件面板的ADO页,如图所示。 ADOStoredPro ADOTable ADOCommand RDSConnection ADOConnection ADODataSet ADOQuery 第8章 数据库编程
8.5 ADO组件 ADO组件与BDE组件的对应关系 第8章 数据库编程
8.5.1 ADOConnection组件 1. 设置ConnectionString属性连接到数据库 连接字符串: 1)直接赋予ConnectionString属性连接串 例如 : Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\paradoxDB; Extended Properties=paradox 7.X; Persist Security Info=False 第8章 数据库编程
8.5.1 ADOConnection组件 2)使用属性编辑器生成连接字符串 (1)向当前窗体上添加一个ADOConnection组件并选中这 个组件,在对象浏览器中双击这个组件的 ConnectionString属性,弹出如图所示的对话框;选中 Use Connection String,单击OK按钮。 设置ConnectionString属性 第8章 数据库编程
“数据链接属性”(Datalink properties)对话框 8.5.1 ADOConnection组件 (2) 系统将弹出“数据链接属性”(Datalink properties)对 话框,如图所示。在“Provider”页中选择数据库驱动程 序。因本例将访问基于Paradox的数据库,因此选择 “Microsoft Jet 4.0 OLE DB Provider”选项。 “数据链接属性”(Datalink properties)对话框 第8章 数据库编程
8.5.1 ADOConnection组件 (3)选择All页,选择其中的Extendedproperties属性,双击 它将显示如图所示的对话框。在该对话框的Property Value上输入“Paradox 7.X”,单击OK按钮。 设置Extended Properties 选择Extended properties 第8章 数据库编程
总是期待选择一个文件而不是目录,因此当使用Paradox数据库时,不要使用Browse按钮。 8.5.1 ADOConnection组件 (4)选择Connection页,如图所示,在“Select orenter a database name:”框中输入包含Paradox表格的目录的 路径。例如输入d:\paradoxDB,它包含数据库student 的4个表。再删除“User name”编辑框的Admin,使之 为空。 总是期待选择一个文件而不是目录,因此当使用Paradox数据库时,不要使用Browse按钮。 第8章 数据库编程
8.5.1 ADOConnection组件 (5)点击Test Connection按钮,出现如图所示的对话框, 表示连接成功,点击确定按钮,再点击OK按钮,退出 属性编辑器。至此完成ConnectionString属性的设置, 也生成了基于Paradox的数据库的连接字符串。 第8章 数据库编程
8.5.1 ADOConnection组件 2. 事务 ADOConnection组件与事务处理有关的方法为BeginTrans、CommitTrans、RollBackTrans和,事件为OnBeginTransComplete、OnCommitTransComplete、OnRollbackTransComplete。它们与Database所提供的事务支持类似。 第8章 数据库编程
8.5.1 ADOConnection组件 【例】利用ADO组件实现数据表的主/从结构。 (1)向主窗体上添加一个ADOTable组件和一个ADOQuery组件; 添加两个Data Source组件;添加两个DBGrid组件。按照表 对 各组件的属性进行设置,这时显示如图所示的界面。 主窗体 第8章 数据库编程
8.5.1 ADOConnection组件 窗体和组件对象属性表 第8章 数据库编程
8.5.1 ADOConnection组件 (2)从这一步开始将设置表之间的主/从关系。将ADO表组件 ADOTabGrad的MasterSource属性设为DSStu,然后双击这 个组件的MasterFields属性,弹出如图所示的Field Link Designer对话框。在该对话框中的Detail Fields列表框和 Master Fields列表框中分别选中“Studentid”字段,然后单击 Add按钮,这时在Joined Fields列表框将添加一项“Studentid —> Studentid”。如果添加错误可以通过单击Delete按钮, 或者Clear按钮将错误的关系删除。正确设置后单击OK按钮。 Field LinkDesigner对话框 第8章 数据库编程
8.5.1 ADOConnection组件 (3)单击工具栏上的RUN按钮运行程序,运行结果如图所示。可 以通过鼠标单击主表中记录而使其成为当前记录,然后观察 显示子表中记录的变化。 运行结果 第8章 数据库编程
8.5.2 ADOCommand组件 ADOCommand组件定义了将对数据源执行的指定命令。 ADOCommand组件主要用于SQL的数据定义(DDL)或执行一个不带返回结果集的存储过程。 一种是指数据操作语言(DML)中的数据更新语句(如Insert,Delete或Update),而Select通常要返回结果集; 另一种是指数据定义语言(DDL)创建或修改数据库服务器端的语句(如表、索引或存储过程)。 第8章 数据库编程
8.5.2 ADOCommand组件 ADOCommand组件属性 CommandText属性 CommandText属性是表示命令(如SOL语句、表名或存储过程)的字符串,默认值为空串(‘’)。如果设置该属性时,将ADOCommand组件的Prepared属性设置为true,并将ADOCommand组件绑定到打开的连接,则在调用Execute或Open方法时ADOCommand将准备查询。 (2) CommandType属性 CommandType属性指示如何处理CommandText属性值,其取值和含义如表所示。 第8章 数据库编程
8.5.2 ADOCommand组件 (3) CommandTimeout属性 命令期间需等待的时间(单位为秒),默认值为30。 (4) Prepared属性 Prepared属性指示执行前是否保存命令的编译版本,设置或返 回布尔型值。 2. ADOCommand组件方法 (1) Execute方法 Execute是ADOCommand组件的主要方法,它执行在 CommandText属性中指定的查询、SQL语句或存储过程。 第8章 数据库编程
8.5.2 ADOCommand组件 【例】使用ADOCommand组件,向codes表添加一条记录“4,法律系,ADOCommand示例”。 ●先在窗体上各放置一个ADOConnection、ADOCommand、 Button组件。再参照8.5.2节设置ADOConnection的 ConnectionString属性连接到数据库student;添加Button1的 OnClick事件处理代码: procedure TForm1.Button1Click(Sender: TObject); begin with ADOCommand1 do begin CommandText:=' INSERT INTO codes '+ ' VALUES (:NewDepartmentid,:NewDepartment, :NewDescription)'; CommandType:=cmdText; Parameters.ParamByName('NewDepartmentid').Value:= 4; Parameters.ParamByName('NewDepartment').Value:= '法律系'; Parameters.ParamByName('NewDescription').Value:= 'ADOCommand示例'; Execute; end; 第8章 数据库编程
8.5.3 ADODataSet组件 ADODataSet是最常用的ADO数据集组件,使用该组件可以从ADO数据库读取一个或多个数据表。可以直接读取数据表,也可以通过SQL语句访问数据表。在使用ADODataSet访问数据之前需要建立它与数据库之间的关联,建立这种关联可以通过设置ADODataSet的ConnectionString属性或者通过设置Connection属性为一个ADOConnectonnection组件。 第8章 数据库编程
8.5.3 ADODataSet组件 ADODataset的属性 (1)CursorType属性 动态游标、键集游标、静态游标和仅向前游标。 在打开ADODataset之前设置可以通过设置CursorType属性 来选择游标类型。如果没有指定游标类型,将默认打开键 集游标。 (2)Connection属性 Connection属性可设置为ADODataset组件当前所属的 ADOConnection组件。 第8章 数据库编程
8.5.3 ADODataSet组件 2. ADODataset的方法 (1)CancelUpdates方法 (2)UpdateBatch方法 该方法将所有在本地缓存的更改写入数据库。若 ADODataset组件支持,则可将一个或多个记录的多重更改 缓存在本地,然后再调用UpdateBatch方法一起更新。 (3)Clone方法 Clone方法创建现有ADODataset组件的副本。这对于希望保 留多个当前记录十分有用。当前记录在新复制的 ADODataset组件将设置为首记录。 第8章 数据库编程
8.5.3 ADODataSet组件 (4)DeleteRecords方法 type TAffectRecords = (arCurrent, arFiltered, arAll, arAllChapters); procedure DeleteRecords(AffectRecords: TAffectRecords = arAll); AffectRecords参数确定Delete方法所影响的记录数目,取值见表: ● 如果在事务中嵌套删除,可用RollbackTrans方法恢复已删除的 记录; ● 如果处于批更新模式,则可用CancelBatch方法取消一个或一组挂 起删除。 第8章 数据库编程
8.5.3 ADODataSet组件 (5)Requery方法 (6)LoadFromFile方法和SaveToFile方法 Requery方法通过重新执行对象所基于的查询,更新 ADODataset组件中的数据。 (6)LoadFromFile方法和SaveToFile方法 公文包方式就是指外出办理业务,不能与数据库服务器相 连,暂时先使用事先备份下来存在文件中的数据,回到网 络环境中后,连接数据库服务器,再把文件中的数据更新 到数据库中。ADO通过使用两个方法支持公文包方式,即 LoadFromFile和SaveToFile,有两种文件格式,即ADTG和 XML。 第8章 数据库编程
8.5.3 ADODataSet组件 ▲语法: LoadFromFile(const FileName: WideString); SaveToFile将查询结果保存在文件中。 procedure SaveToFile(const FileName: String = ''; Format: TPersistFormat = pfADTG); 各参数的说明如下: l FileName:用于保存文件的完整路径名及文件名。 l Format:保存文件所使用的格式,以是下列常量之一: ①pfADTG:默认值,使用专用的Advanced Data Tablegram格式保存。 ②pfXML:使用XML格式保存 第8章 数据库编程
8.5.3 ADODataSet组件 【例】本程序模拟公文包的使用。 (1)程序完成的功能是:当选中“连接数据库复选框”时,应用程 序与数据库student连接,当关闭应用程序时,把修改后的数 据保存于表students中;当未选中“连接数据库复选框”时,应 用程序与数据库student脱离,当关闭应用程序时,把修改后 的数据保存于公文包文件d:\students.xml中。 (2)设计应用程序主界面如图所示,使用的窗体、组件及其属 性值如表所示。 程序界面 第8章 数据库编程
8.5.3 ADODataSet组件 窗体和组件对象属性表 窗体和组件对象属性表 第8章 数据库编程
8.5.3 ADODataSet组件 (3)编写程序代码 const FileName = 'd:\students.XML'; begin LoadData过程,完成数据的装入。如果存在公文包文件 (d:\students.XML),则从该文件装入数据,即把公文包中的数 据更新到数据库中。否则直接从数据库中取得数据 procedure TFormBriefcase.LoadData; begin if FileExists(FileName) then Studs.LoadFromFile(FileName) // 若存在公文包,从公文包中获得数据 else // 选中"连接数据库复选框" // 提示用户目前正与数据库相连;从数据库中获得数据 ConnectionInd.Checked := True; Studs.Open; end; 第8章 数据库编程
8.5.3 ADODataSet组件 UpdateData过程,把数据写入数据库中。该过程完成三件事情: l 选中“连接数据库复选框”,提示用户目前正与数据库相连; l 将缓存中的数据写入数据库; l 将公文包中的数据已经写回数据库中,并且删除公文包 procedure TFormBriefcase.UpdateData; begin ConnectionInd.Checked := True; Studs.UpdateBatch; DeleteFile(FileName); end; SaveData过程。将数据库中的数据备份下来,留待脱离网络环境时 使用 procedure TFormBriefcase.SaveData; Studs.SaveToFile(FileName, pfXML); 第8章 数据库编程
8.5.3 ADODataSet组件 FormCreate事件,调用LoadData过程。程序运行时判别是否存在 公文包文件employee.xml,若存在,则从该文件中装入数据,否 则,从数据库中装入数据。 procedure TFormBriefcase.FormCreate(Sender: TObject); begin oadData; end; FormCloseQuery事件。处理该事件目的是:当关闭窗体时,做一 些善后的工作。如果应用程序正与数据库相连时,把数据已经写回 数据库中;否则应用程序未与数据库相连,处于脱离数据库状态, 此时把处理后的数据写入公文包中。 第8章 数据库编程
8.5.3 ADODataSet组件 procedure TFormBriefcase.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin if ConnectionInd.Checked then ADOConStu.Open; Studs.Connection := ADOConStu; UpdateData; end else Studs.Connection := nil; ADOConStu.Close; SaveData; end; end. 第8章 数据库编程
8.5.3 ADODataSet组件 (4) 运行程序 l 运行程序, 复选框已被选中,说明当前正对数据库 进行操作。 l 不选择 复选框,关闭程序,将会发现自动产生公 文包文件(d:\students.xml),可以用“记事本”打开该文件。 l 再次运行程序, 复选框未被选中,说明当前已处于 脱离数据库的状态,此时可修改数据。关闭程序后,修改 后的数据将写入公文包中。 l 再次运行程序, 选择复选框,此时可修改数据。 关闭程序后,修改后的数据将写入数据库中,并且删除公文 包文件。 第8章 数据库编程
8.5.4 ADOTable、ADOQuery和ADOStoredProc组件 ADOTable组件与Table组件的区别与ADOQuery组件与Query组件、ADOStoredProc组件与StoredProc组件的区别一样。 ADOTable组件与Table组件的区别主要有: (1) ADOTable组件通过ADO与数据库相连,而Table组件则是依靠 BDE。 (2) ADOTable组件除具有与Table组件相同的、用于访问数据库 数据的属性和方法外,还有用于建立组件与ADO数据库之间 联系的属性和方法,如Connection、CommandText、 CommandTimeout、CommandType、ConnectionString等等。 第8章 数据库编程
8.5.5 数据集组件的类结构 数据集组件的类结构图: 第8章 数据库编程
8.6 通过ODBC访问数据库 8.6.1 ODBC基本概念 ODBC(开放式数据库连接)是一个数据库编程接口,由Microsoft建议并开发。ODBC允许程序使用结构化查询语言(SQL)作为数据访问标准,应用程序可通过调用ODBC的接口函数来访问来自不同数据库管理系统的数据。对于任何一种客户机/服务器关系数据库管理系统RDBMS,还是最流行的索引顺序访问方法ISAM数据库(如Jet、FoxPro)以及电子表格等,都有32位ODBC驱动程序。Windows动态链接库(.DLL)组成了ODBC API,对ODBC驱动程序可用到的所有数据库类型,动态连接包括两组函数,可以提供基本的数据库服务。 第8章 数据库编程
8.6.1 ODBC基本概念 数据库服务 添加、配置和删除ODBC数据源。一个数据源是对一个数据库的有名连接,通常称为数据源名称(DSN) 。 管理从客户前端到数据库服务器的查询语句和其他的SQL语句的通信,并且返回查询结果或执行动作要求的反向确认。 ODBC驱动程序 ODBC驱动程序有单层ODBC和多层ODBC两种。单层ODBC不 能直接处理ANSI SQL语句,它将ANSI SQL语句转换为一系列 的低级指令,直接操作数据库文件。Microsoft的单层ODBC驱 动程序用于连接dbase、FoxPro、VisualFoxPro、Paradox、Excel 和文本文件。多层ODBC驱动程序依靠客户机/服务器RDBMS来 处理ANSI SQL语句。 第8章 数据库编程
8.6.2 ODBC数据源配置 (1) 进入ODBC。单击Windows系统开始设置控制面板管理 以下是向ODBC添加新数据源e:\exceltest\student.xls的操作步骤: (1) 进入ODBC。单击Windows系统开始设置控制面板管理 工具,进入“管理工具”窗口,双击“数据源(ODBC)”,打开 “ODBC数据源管理器”对话框。 第8章 数据库编程
8.6.2 ODBC数据源配置 (2) 添加数据源。在ODBC数据源管理器中单击Add按钮,进入如 图所示的“创建新数据源”对话框,选择Microsoft Excel Driver (*.xls)以创建安装excel所需的驱动程序,单击完成按钮,进 入“ODBC Microsoft Excel安装”对话框,如图所示。 创建新数据源对话框 ODBC Microsoft Excel安装对话框 第8章 数据库编程
8.6.2 ODBC数据源配置 为这一数据源填上数据源名(本例为exStu);单击“选择工作簿”按钮,进入选择工作簿对话框,按图所示,在其中选择数据库后,单击确定按钮。 选择工作簿对话框 第8章 数据库编程
8.6.2 ODBC数据源配置 (3)至此新ODBC数据源exStu被创建,如图所示。 成功创建新数据源 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 下面配置BDE与刚建立的ODBC数据源exStu的连接。 (1)运行BDE Administrator,打开Configuration页,从左边的树 形结构中选择ConfigurationDriversODBC,鼠标右键单 击选择弹出式菜单中New命令,如图所示。 创建新的ODBC连接 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 (2)系统将自动弹出“New ODBC Driver”对话框,在“ODBC Driver Name”下拉列表框中选择Microsoft Excel Driver (*.xls),然后在“Select Data Sources to Create A1iases” 列表框中选择“exStu”,在Driver Name文本框中输入 “exStuODBC”,如图所示,单击OK按钮。这时BDE Administrator将在ConfigurationDriversODBC下面创建 一个新的子项“exStuODBC”。 New ODBC Driver对话框 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 (3)鼠标单击BDE Administrator的Database页后,选择主菜单 下的ObjectNew,弹出New Database Alias对话框,如图 所示,选择“exStuODBC”后,单击OK按钮。建立了一个数据 库的别名。 New Database Alias对话框 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 (4)默认情况下,BDE Administrator会给别名命名为“ODBCl”, 单击鼠标右键,选择ReName将“ODBCl”改成“excelStu”。 (5)设置“excelStu”的ODBC DSN,从ODBC DSN的下拉菜单中 选择exStu。 (6)选择主菜单下的ObjectApply命令,将弹出确认修改的对 话框,单击OK按钮,将创建的数据库配置信息保存。这样 就建立了一个基于ODBC数据库的别名excelStu,可以同使用 BDE自带的驱动程序创建的别名一样使用这个别名。 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 【例8.15】建立一个访问e:\exceltest\student.xls的应用程序。使用已建立别名为excelStu的数据库。应用程序主界面如图所示,所使用的窗体、组件及其属性值如表所示。 程序界面(设计时) 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 窗体和组件对象属性表 第8章 数据库编程
8.6.3 配置BDE与ODBC数据源的连接 说明: l 设置TabStu的TableName属性时,需手工写入Students$。工 l 在GrdStu中浏览表格,表students中name字段每栏的宽度是 255个字符,有些不便。这种情况能通过修改字段的Size属性 来改变。 l 如果从IDE运行应用程序,将发现Excel ISAM的第一个限制是 XLS文件应被以独占方式打开。为了运行该程序,将首先需要 关闭在IDE上被打开的应用程序,然后从Windows Explorer运 行它。 l 当运行程序时,该ISAM驱动程序的另一个限制是能添加新行 并编辑已有的行,但不能删除行。 第8章 数据库编程
8.7 数据显示/编辑组件 组件面板的Data Controls页中的组件主要用于显示或编辑数据源提供的数据,如图所示。它们都是数据敏感组件,使用它们可以建立应用程序的用户界面。数据显示/编辑组件将数据表的数据显示在窗体中,并实现与用户间的交互。 DBEdit DBRadioGroup DBNavigator DBImage DBComboBox DBCheckBox DBListBox DBGrid DBText DBMemo 第8章 数据库编程
8.7.1 DBGrid组件 用网格的方式显示数据表中指定字段的数据,并能够让用户编辑这些数据。 1. DBGrid组件属性 第8章 数据库编程
8.7.1 DBGrid组件 属性中Options取值 Options取值 第8章 数据库编程
8.7.1 DBGrid组件 【例】在前面的例子中,对于数据表中的字段没有进行选择,而 是将所有的字段均显示在了DBGrid组件中。对于某些用户界面,由于权限的限制或者使界面更加简洁,往往只显示数据库表中的某些字段。如图界面,在GrdStu中只显示studentid、name、totalscore三个字段;并将显示标题studentid、name、totalscore分别改为学号、姓名、总分。 界面参考图 第8章 数据库编程
8.7.1 DBGrid组件 (1) 鼠标右键单击放置在主窗体上的GrdStu组件,在打开的弹出 式菜单中选择Columns Editor命令,弹出列编辑器;鼠标右键 单击列编辑器,在打开的弹出式菜单中如图选择Add all fields 命令,则列编辑器的显示如图所示。 列编辑器的弹出式菜单 添加全部字段的列编辑器 第8章 数据库编程
8.7.1 DBGrid组件 (2) 通过列编辑器的弹出式菜单的命令和对象观察器来修改字段 的属性。 l 删除Sex、Birthday、Departmentid三个字段。鼠标右键单 击列编辑器中的Sex字段,在打开的弹出式菜单中选择 Delete命令。 l 通过对象观察器改变字段的显示特性。将GrdStu组件的显示 标题studentid、name、totalscore分别改为学号、姓名、总 分。具体方法为在字段的列编辑器中选中studentid,在对象 观察器中,打开Title属性前的“+”号,再选择“Caption”属 性,把该属性设置为“学号”。 除了通过列编辑器的弹出式菜单的命令外,也可以通过列编 辑器工具栏上的一组按钮 进行字段的编辑操 作。 第8章 数据库编程
8.7.1 DBGrid组件 2. DBGrid组件的事件 DBGrid组件的事件 第8章 数据库编程
8.7.2 DBNavigator组件 DBNavigator组件主要用来执行在数据集中浏览数据和编辑数据的操作,如记录定位、插入记录、删除记录、保存用户对记录的修改等。DBNavigator的外观见图,各个按钮功能描述见表。 DBNavigator的外观 只允许浏览的DBNavigator组件 DBNavigator中各个按钮的功能 第8章 数据库编程
8.7.2 DBNavigator组件 重要的属性: DataSource:通过这个属性使本组件与被其控制的数据集联 系起来。 VisibleButtons:决定了本组件在用户界面上显示的按钮的组合。 Hints:程序运行时,鼠标移至DBNavigator某按钮时弹出的提示信息,通过单击Hints属性右边的省略号可以进入提示信息编辑对话框,如图所示。 Hints编辑对话框 第8章 数据库编程
8.7.2 DBNavigator组件 (4)ShowHint:为True时,能在运行时刻显示提示信息。 (5)Visible:决定在运行中DBNavigator组件是否可见。通过对 该属性的控制可以实现在运行中动态地增加或减少 DBNavigator中的按钮。 第8章 数据库编程
8.7.3其他DataControl组件 1. DBText组件 该组件类似于Standard页上的Label组件,DBText组件主要用于显示数据集中的字段类型为文本型的字段值,该组件不能用于编辑数据库中的数据。DEText的WordWrap属性设置为True时,允许当所显示值的长度超过DBText设计时的长度时折行显示。下左图就是通过DBText组件来显示数据库中的信息。用于显示表students中的studentid、name、totalscore三个字段,如下右图所示。 三个DBText组件 三个Label组件 使用DBText组件 运行结果 第8章 数据库编程
8.7.3其他DataControl组件 2. DBEdit组件 该组件能显示和编辑数据源中记录的字段,可以参照DBText组件来建立DBEdit在数据库应用程序中的应用,其部分属性说明见下表。 DBEdit组件的主要属性 第8章 数据库编程
8.7.3其他DataControl组件 3. DBMemo组件 在DBGrid中不能显示数据类型为Graph和Memo字段中的内容,可以使用DBMemo及DBImage分别显示字段中的内容。 DBMemo组件提供了一个显示和编辑数据库中多行文本的工具。下图就是通过DBMemo组件来显示表codes中的 description字段。 使用TDBMemo 第8章 数据库编程
通过DBImage组件来显示数据库的BMP字段 8.7.3其他DataControl组件 4. DBImage组件 DBImage组件提供了一种显示数据库中的Graph字段的 方法,组件的主要属性和方法 如下表: 通过DBImage组件来显示数据库的BMP字段 使用DBImage 第8章 数据库编程
8.7.3其他DataControl组件 5. DBListBOX组件 该组件提供一个列表框,用户可以通过从该列表框中选择值来改变数据库中的当前记录的对应字段(对应字段由 DBListBox组件的DataField指定)。当浏览数据库中的数据 时,当前记录将自动用蓝色光带加亮。 (1)Items属性 DBListBox组件的主要属性除了用DataSource指明相联 系的数据源及用DataField属性指定相联系的字段外,还 有一个重要的属性就是Items。可以点击对象观察器中 Items属性右边的,通过字符串列表编辑器来设置该属性,如 图所示。 第8章 数据库编程
8.7.3其他DataControl组件 6. DBComboBox组件 该组件提供了一种用户既可通过键入数据,又可以通过从选择列表中选择数据两种方法来更改数据库中的数据。该组件的Sorted属性决定是否对DBComboBox中的各项进行排序。 7. DBCheckBOX组件 该组件只有两种状态,即选中和未选中。这为用户提供了表示布尔型字段值的一种直观的方法。DBCheckBox组件可以 用于表示一个只有两个元素的集合。 第8章 数据库编程
8.7.3其他DataControl组件 8. DBRadioGroup组件 该组件通过单选按钮组的选择功能向数据库中的某一字段(一般情况下,该字段可能取到的值的个数是有限的)提供一个值。通过属性Items的设置可以向DBRadioGroup组件内加 入单选按钮。设置Items属性时,在字符串编辑器中的每一项将成为DBRadioGroup中的项。 第8章 数据库编程
8.8其它相关技术 8.8.1使用Database Desktop快速生成QBE查询 QBE(Query By Example)是一种形式化的查询方法,它非常直观,几乎所有的工作都可以由鼠标来完成,若对SQL语言还不太清楚,就可以用QBE查询方式。 第8章 数据库编程
8.8.1使用Database Desktop快速生成QBE查询 【例】通过Database Desktop快速建立表的QBE查询,并能生成相应的SQL语句。从数据库student的students表中获取学号studentid、姓名name和总学分totalscore,同时从codes表中获取该学生的院系名称department。步骤如下: (1) 运行Database Desktop。点击开始程序 Borland Delphi7Database Desktop。 (2) 创建查询。单击主菜单下的FileNewQBE Query。 (3) 选择查询的源数据表。系统自动打开“Select File”文件选择 对话框,在“Alias”下拉列表框选择数据库别名“student”,然 后选择文件“students”,如图所示。选择完毕后单击 按钮。 第8章 数据库编程
8.8.1使用Database Desktop快速生成QBE查询 (4) 系统将新建一个名为【Query:<untitiled>】的窗口,在该窗 口中,单击studentid、name和totalscore的复选框,选中这 三个字段。 (5) 设定查询条件。可以在每个字段下面的复选框右边加入查询 条件。对于多个查询条件,各个查询条件之间通过逗号分隔。 本例中,将选择Departmentid 在“990200”和“990300”之间的 记录。鼠标单击Departmentid字段下面复选框右边的空白区 域,输入“>=990200,<=990300”。见图。 第8章 数据库编程
8.8.1使用Database Desktop快速生成QBE查询 (6) 添加codes表。鼠标单击工具栏上的 按钮,打开 “Select File”文件选择对话框,选择文件“codes.db”。再参考 (4),选择codes表中的Department字段。 (7) 建立students表和codes表之间的联系。在本例中,customer表 和orders表之间应该是按照相同的Departmentid进行合并。 按照下面的步骤进行操作: l 单击工具栏的按钮,使其处于凹陷状态。 l 单击students表Departmentid字段,将该字段的下方增加红 色显示的文本“jionl”。 l 单击codes表Departmentid字段。这个操作将在该字段的 下方增加红色显示的文本“jionl”。 操作完毕后,工具栏上处于凹陷状态的按钮将 恢复 为 状态。 第8章 数据库编程
8.8.1使用Database Desktop快速生成QBE查询 (8) 运行查询观看最终查询输出结果。 单击工具栏上的 按钮运行查询,执行结果如图所示。 第8章 数据库编程
8.8.1使用Database Desktop快速生成QBE查询 (9) 查看SQL语句。单击工具栏上的 按钮可以查看查询使用的 SQL语句,如图所示。从该图中可以看出,Database Desktop 实际上是根据输入的查询要求自动生成用于查询的SQL语句。 (10) 保存QBE查询。选择主菜单下的FileSave,弹出另存为对话 框,在“Alias”下拉列表框中选择数据库别名“student”,然后 再输入一文件名,如“StuQBE”。完毕后,单击“保存”按钮。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder SQL Builder是一个可视化的查询生成器,可以利用这个工具生成Query组件的查询语句,并将其赋予Query组件的SQL属性。同Database Desktop相比,SQL Builder生成SQL查询语句的功能更加强大。 在窗体中放置一个Query组件后,鼠标右键单击该组件,在打开的弹出式菜单中选择“SQL Builder...”,这时将打开SQL Builder。在退出SQL Builder时,会弹出一对话框,单击“Yes”按钮可以将SQL Builder生成的SQL语句保存到Query组件中。 如果要查看SQL语句,则单击工具栏上的 按钮;如果要查看SQL语句运行结果,则单击工具栏上的 按钮。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 添加/删除表 如果要将数据库student中的表students和codes表添加到 SQLBuilder,可以按照下面的步骤进行操作。 (1) 在SQL Builder的工具栏上,单击Database下拉列表框右侧的 箭头,在弹出的列表框中选择数据库“student”。 (2) 单击工具栏Table下拉列表框右侧箭头,在弹出的列表框中选择“students”。这样customer表就添加到了SQL Builder的窗口中。再选择“codes”。这样codes表就添加到了SQL Builder的窗口中。此时SQL Builder窗口如下图所示。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 如果要将codes表从SQL Builder的窗口中删除,可以通过鼠标右键单击customer表,然后在弹出式菜单中选择“Remove Table”即可。 添加表和选定表中的指定字段 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 2. 选择表中的指定字段 如果要生成一条SQL查询语句,要求students表中studentid、 name和totalscore三个字段。只要选中这三个字段前的复选框。 3. 按指定字段排序 通过SQL Builder下方的Sorting页可以对字段排序进行指定。 如在students表中,如果要按照studentid从大到小排列, 可以按照以下步骤进行操作: (1) 选择students表中的所有字段。 (2) 在Sorting页中选择“Output Fields”列表框中的 “Students. studentid”字段,然后单击“Add”按钮,则 “Students. studentid”出现在“Sorted By”列表框中。 (3) 单击“Sorted By”列表框中的“Students. studentid”, 单击 按钮,这时“Students. studentid”右边的 “Ascending”变成了“Descending”,表示由升序变为降序排 列,如下图所示。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 设置字段排序图: 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 4. 设置查询条件 通过Criteria页,可将WHERE子句加入到SQL语句中设置查询 条件。 例如:如果想在对students表记录排序查询结果基础上,只显 示students表中studentid在“990200”和“990300”之间的记 录, 则可通过Criteria页进行此显示条件设定,设定好的Criteria页 操作步骤为: (1) 选中Criteria页,在第1个“Field or Value”列中选择 “student.studentid”,在“Compare”列中选择 “>=”,在 第2个“Field or Value”列中输入’990200’。 (2) 单击表格下方的空白区域,SQL Builder会自动添加一行。 在新一行分别选择“student.studentid”,“<=”和输 入’990300’。通过Criteria页进行查询条件的设置时,下拉 列表框可以用于设置各个条件之间的关系。例如,“ALL”相 当于WHERE子句中的AND关系,而“ANY”相当于WHERE子 句中的OR关系。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 设定好的Criteria页 下拉列表框可以用于设置各个条件之间的关系 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 5. 计算字段 通过Selection页可以指定输出字段的属性,也可以通过其指定 输出计算字段。例如,若要在courses表中输出课程的基本信 息和每学分的平均学时jsx(jxs=hours/score),即可通过 Selection页进行设定,如下图所示。操作步骤为: (1) 选择“courses”表, 选定其所有字段,单击【Selection】页。 (2) 在最后一个空白行的在第2列“Field”中输入“Hours/Score”, 然后将第1列“Output Name”中的“Hours/Score”改为“jxs”。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 设置计算字段图 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 6. 分组 通过Grouping页可以设定分组条件。如在students表中,可按 所在系部号Departmentid进行分组,如下图所示。 操作步骤为: (1)选择students表, 选定其所有字段,单击Grouping页。 (2)在“Output Files”列中选择“Students.Departmentid”,然后 鼠标单击,把“Students.Departmentid”添加到“Grouped On” 列中。 (3)再依次把“Output Files”列中的其余字段添加到“GroupedOn” 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 设置分组条件图 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 7. 多表查询 SQL Builder通过Joins页说明表之间的关联关系,以实现多表 查询。例如从students表和codes表中选择数据,通过 Departmentid建立关联关系,设定好的Joins页如下图所示。 操作步骤为: (1)选择students表和codes表,单击Joins页。 (2)在“Operator”列中选择“=”,在两个“Field”列中分别选择 “students. Departmentid”和“codes. Departmentid”。 (3)选择students表中studentid、name和totalscore;选择 codes表中department。 还可使用如下更简单的方法设定两个表之间的关系:用鼠标左键按住students表的Departmentid字段不放,然后将鼠标拖动至codes的Departmentid松开,这时在students和codes之间就添加了一条连线,而且两个表的Departmentid字段都变成黑体,表明两个表之间的联系建立起来了。 第8章 数据库编程
8.8.2可视化SQL查询生成器SQL Builder 多表查询图 第8章 数据库编程
8.8.3 dbExpress技术 它是一个崭新的跨平台并独立于数据库的数据访问技术,由Borland通过Linux上的Kylix和Windows上的Delphi 6提供。 第8章 数据库编程
8.8.3 dbExpress技术 dbExrpess组件 dbExrpess组件用作dbExpress的接口,其在组件面板上位置如图 所示,该组件与其他数据库访问组件的对应关系列于表。为将这 些组件与其他数据库访问组件区分开来,dbExrpess组件被加以 前缀SQL,表明它们用于访问SQL服务器。 SQLStoredProc SQLMonitor SQLDataSet SQLConnection SimpleDataSet SQLQuery SQLTable dbExrpess组件与其他数据库访问组件的对应关系 第8章 数据库编程
8.8.3 dbExpress技术 基于dbExpress的标准应用程序使用的查询组件见下表: 2. dbExrpess特征 ● 轻量级 ● 可移植 dbExrpess使单向数据集有如下好处: (1)使用单向数据集进行报告。 (2)能在本地缓存中使用单向数据集,如使用ClientDataSet组件提供的缓存。 3. 使用dbExpress技术 基于dbExpress的标准应用程序使用的查询组件见下表: 第8章 数据库编程
8.8.3 dbExpress技术 基于dbExpress的标准应用程序使用的查询组件 第8章 数据库编程
8.8.3 dbExpress技术 【例】建立一个简单的dbExpress应用程序。使用dbExpress技术访问interBase数据库中的表Employee。 1)主窗体和设置组件的属性 窗体和组件对象属性表 第8章 数据库编程
8.8.3 dbExpress技术 程序界面(设计时)图: 第8章 数据库编程
8.8.3 dbExpress技术 2)使用连接编辑器建立SQLConnection组件的连接属性 步骤如下: (1)双击SQLCon,打开连接编辑器,如下左图所示。点击 “增加连接”按钮,选择“Driver Name”下拉列表框值为 Interbase “Connection Name”为dbExIBase。 如下右图所示。 增加连接 设置Database 测试连接 建立新的连接 连接编辑器 第8章 数据库编程
8.8.3 dbExpress技术 (2)在安装InterBase的同时默认装入若干数据库表,这里根据 安装路径,将dbExIBase键域的Database改为c:\program files\common files\borland shared\data\Employee.gdb。点 击“测试连接”按钮,若设置正确,则出现连接成功对话框。 (3)添加的程序代码。 // GrdIntBaseDblClick事件代码,提交内存缓存区中变化的 数据到数据库。 procedure TFormdbExpress.GrdIntBaseDblClick(Sender: TObject); begin CDSIntBase.ApplyUpdates(0); end; 第8章 数据库编程
8.8.4 InterBase Express简介 InterBase Express(IBX)组件是专门针对InterBase开发者的需要所设计的,具有更强的数据访问能力。IBX组件在组件的Inter Base页中,可以与数据模块一起使用,并且它无需借助于BDE数据库引擎。 第8章 数据库编程