(okwary) 小叹的学习园地

与天斗?不够高~ 与地斗?不够阔 与人斗? 脸皮不够厚

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
 
第十八章 Delphi客户服务器应用开发

  客户/服务器的开发工作涉及定义客户/服务器的体系结构, 然后再将该结构与其它一些对于客户/服务器的实现至关重要的系统结构和技术集成起来。Delphi 2.0Client/Sever版支持用户开发客户/服务器结构的应用程序。本章中我们将阐述客户服务器体系结构原理、如何用Delphi构建客户/服务器的环境和Delphi存取远程SQL服务器的编程和注意事项。

 

18.1 Delphi客户/服务器应用开发原理

 

18.1.1 客户/服务器体系结构

 

18.1.1.1 体系结构概述

 

  客户/服务器系统的体系结构有以下两个特点:

是集合智能用户工作站作为有效平台使用

平台和软件之间的互操作性

 

客户/服务器结构包括连接在一个网络中的多台计算机。那些处理应用程序,请求另一计算机的服务的计算机称为客户机(Client)。而处理数据库的计算机称为服务器(Server)。所有用户都拥有他们自己的计算机来处理应用程序。

客户机计算机可以是大型机、小型机或微机。但是由于微机具有成本的优势,因而通常选择它们作为客户机。同样地,服务器通常是一台微机但在需要较大能力时,也可以使用一台大型机或小型机。在数据库环境下,通过若干称作中间件(Middleware)的程序设计接口,客户机可以与服务器通信。这些接口提供应用程序和数据库之间的连通性。

 

 

 

18.1 客户/服务器体系结构

 

  虽然图18.1只有一个服务器,但客户/服务器结构也可以包括多个服务器。然而在这种情况下,每个服务器必定只处理一个不同的数据库或提供一个唯一的服务。(注意:使用两上或多个服务器来处理同一个数据库的结构不认为是客户/服务器系统,相反它是一个分布式数据库系统〕

  表18.1归纳了计算机在客户/服务器系统中的既定作用。

 

  表18.1 客户机和服务器计算机的作用

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━

  客户机功能         服务器功能

   ───────────────────────────

  管理用户接口        从客户机接受数据库请求

  从用户接受数据       处理数据库请求

  处理应用逻辑        格式化结果并传送给客户机

  产生数据库请求       执行完整性检查

   向服务器发送数据库请求   提供并行访问控制

  从服务器接收结果      执行恢复

   格式化结果         优化查询和更新处理

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

18.1.1.2 客户机概述

 

  如上所述,客户机运行那些使用户能阐明其服务请求的程序,并将这些请求传送到服务器。由客户机执行的计算称为前端处理(front-end processing)。前端处理具有所有与提供、操作和显示数据相关的功能。

  客户机软件由网络接口软件、支持用户需求的应用程序以及实现网络能力的实用程序【例如电子邮件(E-Mail)和群件(Groupware)】组成。网络接口软件提供各种数据传输服务。应用程序软件执行具体的任务,如字处理、电子表格和数据库查询生成。实用程序软件通常执行几乎所有网络用户都要求的标准任务。

 

18.1.1.3 服务器概述

 

  在服务器上执行的计算称为后端处理(back-end processing)。后端硬件(back- end hardware)是一台管理数据资源并执行数据库引擎功能(如存储、操作和保护数据)的计算机。在大型机环境下,后端网络(back-end network)提供大型计算机至大容量存储设备、控制器以及文件服务器的连接。在识别、评价和选择适当的服务器平台时,必须考虑将由该平台提供的服务。例如,一个数据库服务器可能需要快速处理能力。其他可能需要执行的网络服务有通信、应用程序、文件访问以及只读存储器(CD-ROM)服务。随着新的应用技术的广泛使用,可被提供的潜在服务还将继续增加。

  服务器软件既包括遵循于OSI或其它网络结构的网络软件,又包括由该服务器提供给网络上客户机的应用程序或服务软件。

 

 

 

18.1.1.4 中间件概述

 

  中间件是一个软件层,它保护应用程序开发人员避免受到各种通信协议、操作系统以及数据库管理系统的影响。它为建立可与以前沿袭下来的应用程序并存的新应用程序打下了基础。

  中间件有好几种类型。它们包括应用程序设计接口(API),远程过程调用(RPC),网络通信、数据库访问以及计算机辅助软件工程(CASE)工具。

  由于客户/服务器系统需要集成各种不同结构的机器和技术,因而应用程序设计相当复杂。选择适当的中间件可以消除程序设计人员为每个单独协议和操作系统编写代码的麻烦。

 

18.1.2 关系数据库体系结构与客户/服务器模式

 

18.1.2.1 关系数据库概述

 

  关系数据库被定义为一种特殊的数据库,其中各个文件(称作关系)以平面文件(FlatFiles)或表的形式保持数据。表必须只含有一种记录类型。每个记录具有固定数目的字段,所有字段皆显示命名。表内的字段内容是各不相同的,不允许重复组(repeating groups)。不含有复制记录和预定的记录序列。

  在构造关系数据库时,必须特别注意关系的内容以及记录的各属性(字段)之间的内在联系。

  关系数据库上的基本操作有选择、投影、连接和除法,选择建立一个含有与原始关系相同列数的新表,但是行只包括那些满足某些特写标准的原始关系行。投影操作指定将被选择的列,因而形成的表只含有原始表列的一个子集。如果在投影操作删除的列中有两个行不同,那么将只有一个记录被转入新的关系。连接操作从两个或多个表中组合信息。两个表中的公用字段用作组合记录的基础字段。在公用字段中具有相等值的记录被连接在结果关系内。

 

18.1.2.2 关系数据库实现的任务

 

  实现关系数据库所涉及的任务分为三组:

DBMS定义数据库结构的任务

将数据库分配给物理存储介质的任务

建立数据库数据的任务

 

执行这些任务的方法取决于所采用的DBMS产品。

  各种不同的DBMS产品提供定义数据库结构的实用程序。这些实用程序使用一种专用的数据定义语言(DDL)。某些DBMS产品含有一些规定,一旦数据库已被定义到DBMS,即将该数据库分配到物理介质。根据应用程序处理的特点,数据可以定位在指定表上或定位在同一磁盘上。它有些DBMS产品偏重于数据库数据的建立。

  如上所述,数据库定义、存储分配以及数据建立过程都将取决于应用需求和所选择的特定DBMS产品的特征。

 

 

 

18.1.2.3 关系数据操作

 

  为了开发数据库应用,需要使用一种语言来表达处理逻辑。关系数据操作语言共有四类:

  ● 关系代数,它是一种语言,提供一组远算符处理关系数据库中的关系

  ● 关系演算,它是一种语言,在该语言中用户指定一组来自关系数据库内数据操作的结果

  ● 面向变换的语言,它们构成一类非过程语言,这类语言将表示为关系的输入数据变换成表示为单个关系的结果。SQL就是一种面向变换的语言

  ● 面向图形的系统,它们为用户提供一个关系结构的图形,如BorlandParadox IBM公司的QBE(Query By Example)

 

  用户可以采用多种方法与关系数据库进行联系:

某些DBMS产品,包括有生成表格的工具并提供表格和报告的处理

通过查询语言提供一个接口,它们执行查询和更新功能;最重要的查询语言是SQL

与关系数据库联系的第三种方法是通过应用程序

 

18.1.2.4 扩展关系系统

 

  众多的销售商都在积极扩展关系模型。这些扩展包括在关系表中存储复杂数据类型、存储过程、触发器以及二进制大对象(BLOB)。目前正在SQL 3标准中考虑的SQL扩展将包括对对象的进一步支持,还有可能包括对用户定义数据类型及嵌套表的支持。向关系模型提供对象扩展的产品包括SybaseInformixOracleBorland

 

18.1.2.5 SQL:集成客户/服务器体系结构的基本链路

 

  SQL为前面讨论的集成客户/服务器体系结构提供一条基本链路。目前美国国家标准局(ANSI)已认可SQL作为操作数据库的正式工业标准。它是许多数据库管理系统(DBMS)产品都采用的数据存取语言。

  SQL允许用户在关系表数据上进行查询、建立新表、存取现有的远程表、操作数据、建立应用程序存取SQL数据,运行SQL语句,处理错误以及访问多个服务器。SQL数据库服务器是多用户关系数据库管理系统(DBMS)

  SQL可以作为一个查询语言用于交互式使用或嵌入在应用程序中。在执行查询时,SQL接受一个或多个关系作为输入并产生一个关系作为输出,结果是一个表或平面文件,例如,一批不含有重复组的同一类型记录。在查询多个表时,SQL将这些表连接起来。SQL内还含有一些规定,用来向表中插入新数据、从表中删除数据或修改表中的数据。

 

18.1.3 各种数据库服务器功能介绍

 

  服务器数据管理包括若干软件,它们使用户可以访问网络中的任何节点以及确保多用户环境下的保密性、可恢复性和完整性。如前面所提到的,客户/服务器计算中的基本存取链路是SQL,它是一种高级非过程数据库语言, 现在已开发出很多支持SQL 的后端服务器及DBMS。下面将描述这些产品。

 

18.1.3.1 DB2

 

  DB2是一种由IBM公司开发的RDBMS。它使用SQL执行所有的数据库操作。数据定义、数据存取、数据操作以及授权功能。SQL语句由用户在一个客户机节点从键盘输入或嵌套在应用程序中。

  DB2的结构包括表、视图、表空间、索引、索引空间、数据库和存储组。 这种RDBMS提供有允许用户动态建立和修改这些结构的工具。DB2还包括一些并行处理软件,以控制和限制干预、后备和恢复功能以及安全性保证等。

  并行处理通过锁来完成,当应用程序读数据库数据时,DB2在该数据上获取一个共享锁,允许其他应用程序读这个相同的数据。如果一个应用程序需要修改数据,那么DB2将一个互斥型锁放在该数据上,以阻止其它应用程序访问这个数据。DB2还提供一些关于锁的级别或锁的大小的任选项。

  DB2周期性地存储并检查所有数据库变化。所有驻留在系统缓冲区中的变化被写到数据库,并将一个变化的记录载入日志。以最近一次写到日志的变化起所建立的全部映像可用于完成系统故障的恢复。DB2包括一些用来从备份拷贝重新建立数据库的实用程序。这种实用程序含有一个选择项,允许用户只拷贝表空间中那些自最后一个备份后新被修改的页面。

  DB2还含有一些用来保护数据库的安全性规定。

 

18.1.3.2 Borland对象成分体系结构(BOCA)

 

  BOCA建立了一个既考虑开发工具又考虑数据库管理工具的客户/服务器体系结构。它将一级面向对象的工具、中间件和数据库服务器技术集中在一起提供客户/服务器的解决方案。该体系结构的组成部分有:

  1. 先进的面向对象工具

Borland建立有广泛基础和紧密集成的面向对象的工具,这些工具充分利用了当前客户/ 服务器变革的优点。使用面向对象的方法学,建立了如下产品:Borland C++Borland DelphiParadoxQuattroProVisual dBase以及ObjectVision等。

  2. IDAPI

IDAPI(集成数据库应用程序设计接口)Borland公司的SQL连通性解决方法。 IDAPI使得开发人员能够以更高的效率建立数据库应用,允许用户在多种硬件和操作系统平台以及网络环境下访问,以多种数据库格式存储的数据。

  3. InterBase

InterBase是一种分布式SQL数据库服务器。它支持每个数据库系统查询数据并将信息返回到其它任何一个InterBase服务器。InterBase 的可变体系结构代表了关系系统技术的第三次浪潮,可变引擎使得InterBase可以以最少的锁支持高效事务处理和决策支持事务处理。

  Borland公司的面向对象技术使得开发人员可以通过构造模块化的应用成分来建立复杂客户/服务器系统。这些模块化应用成分可以很容易地开发、测试、维护和增强,并可方便地装配到复杂的应用程序包中,此外Borland公司的可视化技术极大地提高了软件生产率。

 

18.1.3.3 Informix SQL服务器系列

 

  Informix公司推出了多种产品来满足特定的客户/服务器需求。 它们包括Informix-On-LineInformix TP/XAInformix Star Informix On-Line/OpticalInformix On-Line工作站版。

  Informix-On-Line是一个联机事务处理(OLTP)数据库服务器,具有可用性、数据完整性以及多媒体数据管理能力。它建立有效的数据存储方法进行快速数据存取;缓冲数据于内存最低限度地使用磁盘存取;利用多处理器特征,允许不同处理器同时存取;以及自动确定是有效的搜索策略等,从而获得极高的性能。

  Informix-TP/XAOn-Line连接到事务处理管理程序;支持那些涉及多个数据库以及多个DBMS(由不同的销售商提供)的事务处理。在众多RDBMS中,Informix 第一个向依从于X/Open XA的事务处理管理程序提供了这种基于标准的接口。

  Informix-STAR是一种用于On-Line的分布式客户/服务器数据库产品,它提供最佳的性能,并且具有最小的网络通信量、站点透明性以及在不同站点操作数据库的高度可靠性。

  Informix-On-Line/Optical是一种针对On-Line用户的附加产品。这些用户想在他们的数据库系统上使用具有大容量存储能力的光学设备。On_Line/Optical允许用户在“写一次读多次”(WORM)的光学子系统上存储BLOB。用户必须拥有On-Line/Optical On-Line和一个光学子系统。那当然,如果没有这个On-Line/Optical产品用户仍可以使用On- LIne在磁存储设备上操作BLOB

  Informix-On-Line工作站版是On-Line管理员手册的图形化版本。该工作站版具有与硬件版本相同的技术内容,但它是构造在一个窗口化、点一揿式(Point-and-Click)图形接口,采用关键字交叉查阅。这使得用户可以在某一窗口中存取所需信息的同时,在另一窗口中配置监视或调节On-Line

 

18.1.3.4 Microsoft SQL服务器系列

 

  作为Microsoft SQL服务器系列的一部分,有以下产品:Microsoft SQL Server for Window NTMicrosoft SQL Administrator for WindowsMicrosoft SQL Bridge Microsoft SQL Server程序员工具包。

  Microsoft SQL Server for Windows NT旨在为有关键任务的应用系统管理大型数据库和满足网络化客户/服务器应用的需要。

  Microsoft SQL BridgeMicrosoft SQL Server环境和Sybase SQL Server环境之间提供一个协议网点。

  Microsoft SQL程序员工具包提供开发客户/服务器应用程序的灵活性,这些应用程序将关键的组合信息传送给基于WindowsMS-DOSOS/I的生成系统。

 

18.1.3.5 Oracle RDBMS

 

  Oracle RDBMS为以任务为中心的企业范围的应用提供所需要的操作、监督和管理软件。使用Oracle RDBMS的分布式数据库和网点能力,用户可以透明地集成该企业的新旧数据、系统和应用程序。Oracle被分组形成几个软件包,使得客户可选地获取他们自己的应用所需要的功能。这些软件包是:

标准Oracle软件包

过程化选件软件包

分式式对象软件包

并行服务器选件软件包

开放网关软件包

 

  标准Oracle软件包提供解决大量关键任务的联机数据处理(OLDP)和决策支持应用所需要的功能及性能。这个标准软件除具有其它几个软件包的全部特征外,还有以下标准Oracle软件包所专有的特征:

  1. Oracle的过程化选件(procedual option)

提供多种能力可使数据库服务器成为应用环境的一个有效组成部分,过程化选件非常适用于具有高级需求和复杂商业实施规则的应用。它可选择地包括在Oracle服务器内使用程序设计语言PL/SQL过程的能力。具有存储过程和函数、过程软件包、数据库触发器、锁管理程序软件包以及数据库报警等特点。它还允许交互式提交或从3GL(第三代语言)程序提交“匿名”PL/SQL过程。

2. 分布式选件(distributed Option)允许把一个物理分布式数据库当作一个逻辑数据库来看待。那些需要在多个站点更新数据的应用可以从分布式选件获益。该选件的特征包括:

分布式更新

事务处理(TP)

监控器(XA)接口

透明的二阶段提交

远程过程调用(RPC)

表复制以及Oracle邮件接口

 

对于标准Oracle服务器,还包含查询能力和全局数据库名。

  3. 并行服务器选件(Parallel | Server Option)

提供对松耦合系统多个节点的支持,从而并行存取OLTP和决策支持的一个数据库。并行服务器在高性能、可扩充性、可用性以及数据库连接等领域具有极大的优势。并行服务器选件包括高速缓存(Cache)管理以及松耦合和大规模并行平台所需要的其它所有特征。

  4. Oracle开放网关软件包

提供对非Oracle数据管理程序、文件系统、应用程序和其它各种系统中的数据可编程且透明的存取。Oracle公司采用开放网关技术来向众多流行的数据系统和文件系统提供SQL连接网关,以进行透明的SQL存取。对于那些没有SQL连接产品的目标数据管理程序,Oracle开放网关开发人员工具包可以简化基于开放系统的应用手册的系统、数据及应用的集成工作。

  如果有些部门希望使用基于数据灵敏性或分类的存取控制,那么Trusted Oracle 会包含有Oracle T的所有特征,并具有多级安全性。

 

18.1.3.6 Sybase SQL服务器系列

 

  Sybase SQL客户/服务器体系结构由三个产品系列组成Sybase SQL服务器、Sybase生命周期开发工具和Sybase开放式互操作性产品。

  Sybase SQL服务器是一个针对联机应用的RDBMS。它提供亚秒级响应时间,每用户低成本操作和可用性,SQL服务器智能数据词典收集了众多数据定义、商业规则、报告以及配置信息。

  Sybase SQL生命周期工具提供一种快速原型设计、建立和维护联机应用的手段,使事务处理模型化,实施商业规则保护数据完整性,并将现有应用与新的数据源结合起来。

它们允许开发人员在SQL卡上用生命周期的各个阶段工作。利用Sybase工具,开发人员可以任意组合使用SQL3GL4GL多媒体和面向对象的工具来建立联机系统。

  Sybase的互操作性策略提供用于开发客户机和服务器应用的两种扩展工具包,并面向最通用的RDBMS提供拨动网关(turnkey gateways)。该策略使得复杂计算环境下的多机种硬件,操作系统、网络、数据库和应用程序协同作成为可能。

 

18.1.4 IDAPI结构原理

 

  IDAPI(集成数据库应用程序设计接口)Borland公司解决客户/服务器连通性的方案。也是Delphi 客户/服务器开发的重要组成部分。为了说清楚什么是IDAPI,让我们先来讨论一下普通数据库的接口问题。

每个数据库管理系统和数据库应用都需一定的方式来访问内容所采用的数据格式,连接二者的部分称为接口,其最简单的情况就是对文件的直接访问,也可复杂到由几个层次组成。

  当今,面向用户的数据库通常都直接与其数据打交道,对那些有一定的用户和使用了一定时间的产品尤其如此。制造商总是认为自己的产品就是标准,而不关心对其它数据格式的访问。同样,许多纵向数据库应用用类似C的语言开发,多是直接访问其数据库。对开发者,这样做会变得容易些,但用户的情况往往是多变的。他对底层数据格式的选择并不一定与产品一致。其实在ODBCIDAPI等尚未推出的前20年里,工业界已经认识到,一个DBMS不只是要访问其自身的数据格式。

  广义地讲,数据库接口可分为以下两类:

  ● 本地型(Local)

  ● 客户/服务器型(Client/Server)

 

18.1.4.1 本地型数据库接口 

  本地型数据库是伴随微机的产生而产生的。dBASEII作为最早的并仍在使用的系统之一就是典型的本地型数据库。 

 

  本地型数据库管理系统的数据存放在一个本地硬盘上。DBMS接受来自用户或用户程序的命令。这些命令通常是系统特有的数据库管理语言。命令被转换为简单的磁盘访问命令,并交付文件系统来处理。然后DBMS接收来自磁盘上的数据,并加以处理。

  在本地型DBMS应用中,数据库引擎(DBE)运行于工作站上。图18.2暗示数据是存放在工作站的局部驱动器上,其实在网络中,数据还可存放在文件服务器上。这里数据库引擎使用典型的文件I/O调用和记录封锁技术来直接读写数据。 

  存放数据的文件位于网络中的某个服务器上时,DBMS的行力与单机情况无异。 网络操作系统负责对服务器的管理,因此对DBMS而言,对服务器的使用就象使用局部的驱动器一样。

  当用户发出命令,请求DBMS读取数据库中的数据时,该请求首先由工作站(客户)的网络驱动程序处理,它负责把请求从网络上传到所需的服务器网络文件系统。服务器操作系统从适当的磁盘卷上找到数据,并发回等待中的工作站驱动程序。最后,数据回传给DBMS,这样DBMS使用这些数据就象使用本地存储的数据一样。网络情况下的接口比单机情况下接口的处理增加了通信开销,正常情况下这种额外开销不会影响用户的响应时间,除非在网络通信的高峰期间或DBMS要求大数据量传递。

  对于本地型DBMS其大部分工作都在工作站一侧完成,即使数据存储在文件服务器上,其对数据的处理仍然要在工作站上进行。这种方式的最主要的一个缺点是无论查询需要多么少的数据,都需要首先将查询中的所有数据通过网络传到工作站,然后由工作站负责选出满足查询条件的数据,不难想象,当几个用户同时操作数据库时,数据库网络的带宽会很快阻塞。

  在这一方式下,工作站不仅要负责所有用户界面管理,还要负责所有数据处理的工作。在当今的数据库应用中,尤其是那些功能强且使用简便的系统,用户界面的处理开销是相当大的,象Windows这样的图形环境,处理上的额处开销会更大。为此而升级工作站是很得不偿失的。

 

18.1.4.2 客户/服务器型数据接口

 

  由于服务器硬件技术逐年迅速地提高,数据库在处理模式上在近五年内发生了改变。本地型DBMS逐渐让位给客户/服务器型DBMS,尤其是在大中型企业中更是这样。

  正如名字所暗示的,客户/服务器是将处理工作分散到工作站和服务器上去处理,服务器不仅负责存取数据,还要对数据作一定的处理工作,这样在数据发送给工作站之前即求得查询结果集,从而在大部分情况下可大大减少网络传输的开销,因此,也减轻了工作处理负担,从而只需关心用户界面的处理工作即可。

  服务器处理数据带来的另一个好处是,当服务器中数据库引擎使用了缓冲机制时,多个工作站可以从中受益。例如,一用户查询了某数据,当另一用户要查询同样的数据时,即可从服务器缓冲中直接得到结果,从而免去很多开销。

  客户/服务器系统的成功与否在很大程度上依赖于服务器硬件质量和容量。用户越多,服务器的处理负担越重,相应服务器硬件性能也要跟得上,否则就会导致响应时间比本地型数据库还要差的结果。  

 

  处理工作,而工作站负责用户界面处理工作 

  客户和服务器间的数据库接口要比本地型系统复杂得多。它有几个转换级负责命令和结果集在工作站和服务器间的传送。图18.5给出了客户/服务器数据库接口的详细情况。 

  客户/服务器的前端应用程序实际上不直接与数据库引擎打交道。每个客户服务器提供一个数据库通信接口,该数据库通信接口运行于前端。这些接口也称为数据库通信API等。数据库通信接口的工作流程如下:

  ① 前端应用程序发送命令给数据库通信接口。

接口通过网络把命令传给数据库引擎。

 ③ 数据库引擎在服务时上做查询或更新操作之类的工作,通过网络文件系统访问物理数据。

  ④ 数据库引擎将结果返送给工作站上的通信接口。

  ⑤ 前端从接口上接到结果后,显示或按用户要求做其它处理。 

  客户/服务器型比本地型DBMS更接近ODBC的原理。因为由前端向数据库的命令发送和由数据库向前端结果的返回都是透明的,并不需知道具体传送方式如何,各系统存在差别地方是:客户/服务器系统在管理工作站和服务器间通信的方式不同,彼此会不兼容。此外,对于本地型DBMS缺乏读取不同类型数据源的能力的问题。这些问题在IDAPI中得到了有效解决。 

 

18.1.4.3 Borland Delphi 的解决方案 

  IDAPI是通过BDE(Borland Database Engine)SQL Links,来解决本地型数据库接口和客户/服务器型数据库接口的兼容问题的,见图13.1

  Delphi 的数据库特性使你能很容易构造数据库应用程序。这些应用程序能访问Visual dBASEParadoxLocal InterBase Server for Windows等本地数据库和OracleSybaseInformixSQL ServerRemote InterBase Server等客户/服务器数据库。

BDEBorland公司支持Delphi 2.0 Client/Server SuiteParadox for WindowsVisual dBASE for Windows等产品的核心数据库引擎和互连软件。BDE 提供了丰富和强壮的特性支持客户/服务器应用的开发。

  提供支持多种数据库如dBASEParadoxTextInterBaseOracleSybaseMicrosoft SQL Server以及任何ODBC数据源的统一和一致的应用程序编程接口(API)。开发者能不用修改数据库应用就能访问不同的数据库站点和数据库格式:

  BDE是用于开发客户/服务器数据库应用的理想工具,数据库应用程序既可访问本地数据库又可访问远程数据库

允许数据库用直接和灵活地访问数据源

BDE对于ParadoxdBASE文件格式来是高性能的数据库引擎

  支持使用ISAM(Indextd Sequential Access Method)SQLQBE访问数据

  BDE是数据集成化引擎,提高跨不同数据库的共享服务。支持不同数据库格式的相互转化,如dBASEOracle表、从InterBaseParadox拷贝数据甚至建立InterBase Oracle表之间的一对多关系

  BDE查询引擎为SQLQBE和面向集合访问提供一致性的查询语言。支持用户定义和访问基本SQL的服务器和基于文件数据库的能力

  BDE支持全32位功能,如多线程,抢占式多进程,长文件名和UNC,用户可在后台执行多个查询,多个数据库应用可访问同一个数据库文件

 

  BDE的体系结构是基于数据库驱动程序的,它提供了各种共享服务:

  ● 缓冲区管理(Buffer Manager)

  ● 排序引擎

  ● OS服务

  ● 内存管理

  ● BLOB快速存取

  ● SQL查询引擎

  ● SQL产生器

  ● 数据库重构

  ● 表的批处理

  ● 数据转换服务

  ● 连接服务

  ● 内存数据库服务

  ● SQL驱动程序服务

  ● 系统管理

  ● 语言管理

 

  ParadoxdBASE和文本数据库BDE包含的数据库驱动程序支持对标准数据源的一致性访问。用户可以增加ODBC驱动和Borland SQL Links产品以支持对SQL 服务器的数据访问,如InterBase OracleSybase等。此外BDE给予Windows 95Windows NT应用开发者以直接、独立共享的对多种数据源的高级访问。

  BDE在设计上是面向对象的。在运行时,数据库应用通过建立各种类型的BDE 对象与BDE交互,这些运行的对象用于操作数据库实体如数据库表、查询。BDE的扩展的API支持CC++Delphi等对数据库引擎的访问。

  在Delphi应用程序中访问数据库是通过调BDEAPI函数。Delphi在库单元BDE中提供了大约三十多个API函数和各种BDE消息和结构。由于Delphi应用程序的开发是基于部件的,有关BDE API的调用都嵌入了Delphi可视部件类库,因此,建立数据库应用时可以不必管BDE API的细节。只要正确安装IDAPIDrivers,并进行正确的配置,就能使你的数据库应用程序与服务器连接并访问数据库。当然为了提高应用程序的数据库访问性能, 可以在程序中直接调用BDE API函数。

  BorlandIDAPI包含对ODBC的支持,因此通过BDE,你的应用程序能访问一切与ODBC兼容的数据库如AccessBtrieve

  Local InterBase Server提供了一个单用户多实例的SQL服务器平台,特别是在将数据库应用程序转移到对OracleSybaseInformix等远程数据库的访问之前,可以在Local InterBase Server平台建立和测试数据库应用程序。

  对客户/服务器型的数据库应用程序来说,SQL LinksDelphi数据库体系结构中起着至关重要的作用。

  Borland SQL Links支持访问局部(Paradox dBASE)和远程SQL数据库的BDE应用程序。为了访问特定的远程SQL服务器必须在客户端安装相应的SQL Links驱动程序。安装了SQL Links驱动程序后,SQL表达式才能被传送给相应的服务器执行。

  一旦你安装了SQL Links的驱动程序并建立SQL驱动程序的Alias,你就能采用下列方法使数据库应用程序象访问本地ParadoxdBASE数据库一样访问远程数据库:

  通过应用程序用户接口(界面)

通过包含嵌入SQL表达式的应用程序

直接将SQL表达式传送给服务器

 

  BDE也支持应用程序使用SQL访问局部数源,

  安装了SQL Links驱动程序,你能用SQL访问数据。驱动程序负责SQL服务器的链接,将查询语句转换成兼容的SQL语句并将它们传送给SQL数据库。等处理完成后,SQL数据库把结果以应 

   BDE客户查询SQL数据库;

   SQL Links驱动程序建立客户工作站与SQL Server的链接,并将查询发送给SQL

服务器;

   SQL服务器进行SQL表达式的错误和语法检查,处理查询并将结果返回给BDE

客户;

   SQL Links驱动程序将结果通过SQL转换成客户端能识别的形式,客户端将其进

行格式化并将数据显示给用户。

 

  在应用程序中使用SQL Links驱动程序对使用SQL的数据库具有如下好处:

  ● 直接查询SQL服务器的能力

  ● 支持SQL网络的传输

  ● 增强了记录的快速存取

  ● 数据锁定

  ● SQL结果集和数据库表的双向变换

  ● 使用索引给数据排序

  ● 为数据库当前Session建立书签,并可在以后重用书签

  ● 通过动态访问数据源来动态处理SQL数据

 

18.2 Delphi客户/服务器应用开发环境的构造

 

18.2.1 Borland SQL Links 的安装

 

SQL Links的安装过程如下:

 ⑴ 在客户端工作站上将SQL Links1号磁盘插入软盘驱动器.A:B

Windows 95的资源管理器中,选择运行A:\INSTALL( B:\INSTALL),并显示打开对话框。

  选择Continue 或按EnterINSTALL 检测工作站上是否已安装了BDE 的动态链接库IDAPI01.DLL 。如果需要它将显示一个对话框,以让你描述该文件所在位置。当定位IDAPI01.DLL后,INSTALL显示Borland SQL Links目录对话框,描述你想安装的SQL Links驱动程序。

  当你完成这些工作,选择Continue或按Enter.INSTALL显示IDAPI配置定位框。

  描述你想安装的IDAPI配置文件的升级版的位置。当你完成这些工作后,选择Continue或按Enter。在继续安装之前按照你所选择的驱动程序。安装程序将需要更多的信息,后面的章节中将叙述这些信息。

  ⑸ 一旦你提供了所有的必要信息,安装开始当安装结束后,你能选择察看SQL Links自述文件——READLINK.TXT。阅读这个文件将找到最新的信息。

 

18.2.2 配置SQL环境

 

  与你的BDE应用程序一起安装的有BDE配置工具(BDECFG32.EXE),该工具帮助用户修改他们的应用程序配置。配置参数被存于命名为IDAPI32.CFG的二进制文件中。当应用程序启动时,将读这个文件。通常该文件在应用安装过程中被置于BDE文件目录中(C:\Program Files\Common\BDE)

  本节描述怎样使用BDE配置工具设置应用程序的SQL环境。一旦配置好BDE应用环境,就可开始联接网络,并访问SQL服务器。

  关于怎样使用BDE配置工具的详细介绍,可参见BDE用户指南或按运行BDE配置工具选择Help按钮显示在线帮助。

  在开始配置SQL环境前,必须已完成以下工作:

  已安装SQL Links软件

  退出所有其它Borland应用程序

  Windows 95中打开应用程序组Borland Delphi 2.0

  选择IDAPI配置工具图标,出现配置工作窗口后进入驱动程序管理页

 

18.2.2.1 配置SQL Link驱动程序缺省设置的方法

 

  SQL Link驱动程序缺省设置是指在BDE配置工具的Drivers页中的参数设置,这些参数在建立新的Alias中使用。Alias是描述网络资源的一组参数的集合。BDE应用使用Alias 联接共享数据库。Alias对于访问局部数据库并不是必要的,但要访问SQL数据库,却是必不可少。

  SQL Links驱动程序的缺省设置,是你建立新的Alias 的原型。尽管你在建立Alias后能定制它,但在建立新的Alias前设置相应的缺省设置要来的容易。因为这样建立的每一个Alias将继承这些设置。

  要描述驱动程序的缺省设置,要完成以下几项:

 ● 将亮条移到驱动程序的入口,驱动程序管理程序显示所有的该驱动程序的配置参数,在参数列表表端可用滚行杠检察各配置参数

  ● 如果需要编辑驱动程序的缺省配置参数,如果光标停在这格, 配置工作将自动套用缺省参数

  ● 当完成这些工作,选择File|Save,修改将在应用程序下一次启动时生效

 

18.2.2.2 SQL Links驱动程序的缺省设置项目的含义

 

  1. VERSION

SQL Links驱动程序的版本号。

  2. TYPE

描述当前驱动程序类型。SERVER就表示该驱动程序用于连接一个SQL服务器,FILE就表示驱动程序用于连接一个标准的基于文件服务器。

  3. DLL选项

所选SQL Links16位驱动程序的动态链接库名。

4. DLL32

所选SQL Links32位驱动程序的动态链接库名。

5. DRIVER FIAGS

内部的产品描述标志。

6. TRACE MODE

描述记录跟踪信息的类型

  7. SERVER NAME

指定目标SQL服务器名。如果指定为InterBase服务器,将包含数据库文件的全部路径,Servername:/Usr/gds/directoryname/databasenam.gdb

  8. USER NAME

访问SQL服务器的缺省用户名。

  9. OPENMODE

OPENMODESQL Links打开SQL数据库时的读写模式。取值可以是READ/WRITEREAD ONLY,缺省值是READ/WRITE。把OPEN MODE设为READ ONLY,将影响用户端的操作,但对SQL服务器没有影响。

  10. SCHEMA CACHE SIZE

描述被贮存视图信息的SQL表个数。取值范围是0-32 缺省值为8

  11. LANGDRIVER

用来操作来自SQL 服务器的数据的语言驱动程序。当光标停止LANGDRIVER域时,一个滚行框出现在正文域的左侧,用滚行杠可以用于你的驱动程序的可选的语言列表。如使用美国英语,该缺省值是空格。

  当描述的语言驱动程序与一个服务器别名相适应,那么你的应用程序将使用该驱动程序处理从服务器发来的数据。这包括你察看的所有表和所有查询返回的结果表。运行在不同系统上的服务器利用字符集的转换来决定怎样对数据编码。如果你操作在非英语环境,你的BDE应用程序可以使用不同于SQL服务器的字符集。如果你的平台上的字符集同SQL服务器上的不匹配,那么在两种不同平台间传递数据将引起下列问题:

 ● 数据在你的平台上不正确的显示

  ● SQL数据库上将记录错误的字符

 

  为防止这种情况的出现,SQL Links提供语言驱动程序,实现你的应用程序的字符集与SQL数据库的字符集的数据转换。这将使从SQL服务器传来的数据在你的平台上正确显示,或将你输入的数据可靠地传送到服务器上。

  语言驱动程序包含有关排序和大小写转换的信息。无论何时,对SQL数据库的查询按本地数据库的规则处理应用程序的语言驱动程序用于评测排序的字符范围。 如果平台上的排序和大小写转换与SQL服务器上的不同,你的应用程序就会显示不一致的结果。

  如果SQL数据库使用扩展字符集,请确信用于访问SQL 服务的别名中描述正确的,SQL Links语言版本选择的驱动程序的字符集应当与SQL服务器的相同。如果你没有找到合适的SQL Links语言驱动,你可修改别名中的SQLQRYMODE入口,防止按局部数据库规则处理查询。

12. SQLPASSTHRU MODE

描述应用程序访问SQL服务器时是否借助平台命令和传递式SQL。取值范围和它们的含义列于下表:

 

   18.3 SQLPASSTHRU MODE设置

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

设置            含

  ──────────────────────────────────────

  NOT SHARED    传递SQL和非传递性SQL不共享相同的连接

  SHARED AUTOCOMMIT  缺省值。传递SQL和非传递SQL将共享相同连接,传

递式SQL将以与非传递SQL相似的方式动作。 也就说

用户的传递式SQL表达式将被自动提交。

  SHARED NOAUTOCOMMIT 传递式SQL和非传递式SQL将共享同一个连接,但SQL

驱动程序并不自动提交SQL表达式。在这种模式下,传

递行为是服务器独立的。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

 SHARED AUTOCOMMITSHARED NOAUTOCOMMIT 模式并不支持所有的传递式表达式。当SHARED AUTOCOMMITSHARED NOAUTOCOMMIT模式被设置,在传递式SQL中不需执行事务控制语言。使用你的BDE应用编程语言来开始,提交回送事务。当传递式SQL和非传递式SQL共享一个连接,记录快存并不立即反映传递SQL操作的更新。

  13. SQLQRYMODE

描述处理查询SQL数据的方法。取值范围含义列于下表,缺省值NULL

 

18.4 SQLQRYMODE设置

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  设置      模 式     

  ──────────────────────────────────────

  NULL    Server-Local  在Server-local,查询模式查询首先传递给SQL

务器,如果服务器不能执行查询,查询就在本地执

行。

  SERVER Server-Only Server-Only查询模式,查询被发送给SQL 服务

                 器。如果服务器不能执行查询,不执行本地查询。

  LOCAL Local-Only local-only模式,查询总是本地执行。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

正常情况下,查询SQL数据库将在数据库服务器端被处理。然而,在某些情况下,完全在SQL服务器端执行的查询的结果不同于在本地执行的查询的结果。例如,你的BDE 应用程序查询函数执行在字符域的大小写敏感搜索。如果,服务器不支持大小写敏感搜索,那么Select语句的条件如“>A”在不同地方查询将产生不同的结果。 如果你想确信所有来自BDE应用的查询都按照SQL服务器上的规则来执行,那么你就应合理配置SQL Links驱动程序,阻止查询的本地处理。使用BDE配置工具修改SQL数据库别名,将SQL QRYMODE设置成SERVER就可做到这一点。新的SQLQRYMODE值将在应用程序下一次启动时生效。

  14. SCHEMA CACHE TIME 

描述表信息将被贮存多长时间,取值范围和它们的含义列于下表,缺省值为-1

 

18.2 SCHEMA CACHE TIME设置表

  ━━━━━━━━━━━━━━━━━━━━━━━━━

设置

─────────────────────────

-1 表被贮存至你关闭数据库

   0        不贮存表

  12147483647  贮存表的时间数(秒为单位)

  ━━━━━━━━━━━━━━━━━━━━━━━━━

 

  设置该值能提高数据库表的访问性能。

15. MAX ROWS

描述SQL Links驱动程序能给服务器传递的SQL语句的最大行数。如果值为-1,则没有限制。

16. BATCH COUNT

描述在自动提交前包含在BATCH中的修改记录个数。

 

18.2.2.3 建立和管理SQL别名

 

  设置标准别名的过程包括给Alias参数赋值,描述包含ParadoxdBASE文件的路径名和目录名。设置用于SQL数据库的别名包括给alias赋名,定制用于SQL服务器和数据库的访问参数。SQL别名包括目标SQL服务器的用户名和口令。这些参数对于访问任何SQL数据都是必须的。常用的SQL别名是当安装时,第一次修改缺省的SQL Link驱动程序的参数时自动建立。

  关于如何使用配置工具增加、修改和删除别名,请参阅附录。

 

18.2.2.4 联接SQL服务器

 

  当应用程序第一次访问SQL数据库,会触发一个自动联接过程。联接过程需要确认访问数据库的权限。

  如果配置文件和SQL Link驱动正确配置,应能用应用程序的File菜单通过相应的数据库别名在你的SQL数据库中选取一张表。下面介绍如何解决联接InterBase服务器过程中出现现的一般问题,并讨论有关使用Borland SQL Links的各种主题。

  1. InterBase服务器需求

  下表所列软件应当已经安装在运行InterBase的服务器

 

18.5 InterBase服务器软件要求

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  项 目       描

  ────────────────────────────────────

  数据库服务器软件   InterBaseV4.0或更高版本

  网络协议软件     与数据库服务器和客户工作端网络协议兼容的网络协议

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

2. 客户工作站需求

  下表所列软件应当已经安装和运行于客户工作站,表中还列出相关文件和参数。

 

18.6 客户工作站软件要求

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  项目          描述

  ──────────────────────────────────────

  BDE应用程序    被支持BDE应用程序,并已按产品文档要求安装

  硬件和操作系统   1.5MB剩余磁盘空间,适合Borland Delphi需要的硬件和操作

            系统

  访问网络服务器的  如果你的Borland Delphi被安装在网络文件服务器上,请确

  权力        认对BDE文件安装目录有读写的权力

  网络协议软件    网络协议软件应当与服务器网络协议和客户工作端的客户数

            库通信驱动程序兼容。InterBase支持Windows 95 WinSock API

  HOSTS文件    HOSTS文件包含你要连接的服务器的名称和地址:

例如:128.127.50.12 MIS_Server

SERVIDES文件   一个SERVICES文件包含访问InterBase服务器的协议。 SQL

Links安装过程中,“gds_db 3050/tcp”被加入这个文件

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

3. 安装的软件项目

  当你安装InterBase SQL Link驱动程序,下列项目将被安装于你的工作站上。 

 

18.7 安装的文件名

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   目        描

  ──────────────────────────────────────

  SQLD-IB.DLL 包含InterBase驱动程序和支持文件的动态链接库

SQLINT32.DLL

  INTRBASE驱动类型  加在配置工具的驱动管理程序中以配置基本的Borland

InterBase SQL Link驱动程序

  INTRBASE别名类型  加入配置文件的别名以使建立联接SQL服务器数据库的

别名

  SQLD_IB.HLP 配置InterBase驱动程序的帮助文件

  READLINK.TXT Borland SQL Links for Windows自述文件

  INTERBAS.MSG InterBase消息文件,通常安装上C:\INTERBAS

CONNECT.EXE 测试工作站和InterBase服务器连接情况的工具

  REMOTE.DLL InterBase的支持动态链接库

  GDS.DLLGDS32.DLL

InterBase服务器描述 安装过程修改工作站的SERVICES文件以增加用于

  加入SERVICES文件  InterBase 服务器访问所需的协议描述

如:gds- db 3050/tcp

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

  软件项目中还应包括TCP/IP接口软件

  下表列出的文件给InterBase客户端应用提供访问Winsock 1.1的接口

 

18.8 TCP/IP接口软件

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   名       描

  ────────────────────────────────

  MVWASYNC.EXE 异步通信模块

   VSL.INT TCP/1P传输初始化文件

  WINSOCK.DLL Windows Socket动态链接库

   MSOCKLIB.DLL Windows Socket调用映射到VSL驱动程序

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

  如果TCP/IP产品不是Winsock1.1兼容,InterBase客户端应用将也可采用其它TCP/1P 驱动程序。InterBase服务器还可支持其它通信协议,如SPX/1PXNetBeIU等。

4. 解决一般的联接问题

如果用SQL Links建立与InterBase服务器的连接有问题可采用下列步骤来分离问题原因:

通过Windows ISQL工具测试能否与InterBase服务器联接

如果成功,状态信息会出现,并继续步骤⑵。

如果不成功,询问数据库管理员。

检验InterBase SQL Links 驱动程序是否正确安装。

重新安装SQL Links

检查SERVICES,文件中应有行:

 

gds_db 3050/tcp

 

如果不能正确安装,就请询问数据库管理员,否则继续步骤⑸。

测试底层协议

输入TELNET命令,确认TCP库是否正确安装。

如果TCP库正确安装,注册提示符会出现。注册入网检查数据库是否存在。

如果消息是“can't resolve hostname 出现,检查工作站的HOSTS文件是否有你 的主机名和IP地址的人口。如:

 

128.127.50.12 mis_server

 

如果用TELNET是成功的,但仍然无法正确联接,则没有正确安装InterBase。请寻

求数据库管理员的帮助。

PING到服务器服务器上,测试InterBase服务器是否正常运行并且为桌面应用可见

(如果PING是成功的,消息“servername is alive”被显示)

PING成功但TELNET不成功,则inet daemon可能有问题。

如果PING到服务器上不成功,则有网络路径问题,将问题报给网络管理员。

 

如果底层协议不正常,请询问数据库管理员,否则继续帮助⑹。

确认是否有InterBase服务器的访问权,如果有请继续步骤⑺。

检查BDE应用程序的InterBase别名是否正确安装。

如果能够直接从工作站上联接,但不能从BDE应用程序中,那么很有可能你的

IDAPI32.CFG别名设置有问题。运行BDE配置工具检查InterBase别名。

 

 

18.3 Delphi Client/Server编程

 

  本节介绍如何运用Delphi可视化开发工具和ObjectPascal语言开发Client\Server的数据库应用程序,采用的例子是CSDEMOS。这是Delphi2.0自带的演示Client\Server开发的例子,它安装在C:\Program Files\Borland\Delphi 2.0\Demos\DB\CSDemos(缺省安装)

  本节将包含以下内容:

使用TDatabase部件连接SQL服务器

  ● DataSet部件(又称数据集部件),如TTableTQuery,联接TDatabase部件并访问数据库以及各种表之间如何切换

  ● 使用数据库连接

  ● 触发器的使用方法

  ● TStoredProc部件的使用方法

  ● 客户和服务器之间的事务控制

  ● TStoredProc部件的使用方法

 

18.3.1 使用TDatabase部件联接SQL服务器

 

18.3.1.1 TDatabase部件概述

 

  TDatabase部件处理应用程序与单个数据库的联接。如果不需要控制数据库联接,可以不用创建TDatabase部件。当应用程序试图打开数据库表(Table)时,会自动创建一个临时的TDatabase部件。但如果你想控制数据库的持续联接、进入数据库服务器的注册和数据库别名的值或事务控制,那么你就必须为每个所需的联接创建一个TDatabase部件。

  1. 创建TDatabase部件

  TDatabase 部件在Component Palette中的Data Access页上,你能将其拖放在数据模块(Data module)或窗体中。在设计时创建TDatabase 部件,用户可以设置初始值和编写OnLogin事件处理过程(Event Handle)OnLogin事件给用户提供了第一次注册数据库服务器时定制服务器安全参数,如口令,的能力。

  2. TDatabase的关键属性

DatabaseName属性

DatabaseName是所要联接的数据库名,并且用于DataSet软件,它将出现在DataSet部件的DatabaseName属性的下拉式列表框中。设置DataBaseName属性是定义数据库应用的特定别名。DataSet部件能引用该名字以取代直接使用BDE别名。当TDatabase部件的Connected属性为True时不能修改该属性。

  ⑵ AliaName属性

AliasNameBDE配置工具定义的BDE别名的名字。TDatabase 从中获取其缺省的设置。如果设置DriveName属性,则该属性将被清除,如果当ConnectedTrue 时强行设置DriveName属性将引发异常。

  ⑶ DriveName属性

DriveNameBDE驱动程序,如STANDARD ORACLESYBASEINFORMIXINTERBASE的名字。如果设置AliasName,则该属性值将被清除。

  ⑷ Params属性

Params属性包含了打开SQL服务器上数据库时所需的参数。在缺省情况下,这些参数由BDE配置工具设置;用户也可以用数据库参数编辑器(Database Parameters Editor)修改这些参数。对于数据库服务器而言,Params将描述一系列的参数,如服务器名、 数据库名、用户名和口令。

  ⑸ Connected属性

  Connected属性指明是否建立数据库的联接,当应用程序打开数据库中的一个表时Connected将被置为True;反之,关闭数据库表,Connected将被置为False,除非KeepConnectionTrue。而将Connected置为True则可不需打开数据库表即可建立数据库联接。TDatabaseKeepConnection属性描述当数据库中没有表打开时是否维持数据库联连。

  ⑹ KeepConnection属性

  KeepConnection属性描述当数据库中没有打开表时是否要保持与服务器的联连, 如果数据库应用需要打开和关闭单个数据库中的多个表时,将KeepConnection 设置为True是很有用的,那样,即使没有打开任何表,应用仍能保持与数据库的联接,它能够重复地打开和关闭数据库表,而不需要重复执行联接过程。如果KeepConnection置为False,当每次将Connected置为True,数据库都必须执行注册过程。

  ⑺ LoginPrompt属性

  LoginPrompt属性用于控制如何处理SQL数据库的安全性问题。如置为True,当应用程序试图建立数据库联接时屏幕上将出现标准Delphi注册对话框。用户必须输入正确的用户名和口令。如果置为False,则应用程序将寻找TDatabase部件的Params 属性中的注册参数。下面是USERNAMEPASSWORD参数的例子:

 

  USERNAME = SYSDBA

PASSWORD = masterkey

 

  ⑻ TransIsolation属性

  TransIsolation属性描述SQL服务器所有的事务控制独立级别。 tiDirtyRead使所有修改都被返回,而不管记录是否已被提交。tiReadCommitted将只返回提交的记录,而提交的修改将不会在结果中反映出来。tiRepeatableRead 将只返回事务过程中最初的记录,即使另一个应用程序将所作的修改提交。

  各种数据库服务器可能不同程度地支持这些独立级别,或者根本不支持。 如果需要的独立级别不被服务器支持,那么Dephi将使用下一个更高的独立级别,如下表所示:

 

18.10 各类服务器TransIsolation设置

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  独立级别     Oracle Sybase和     InterBase

Microsoft SQL

──────────────────────────────────────

Dirty Read Read Committed Read Committed Read Committed

Read Committed Read Committed Read Committed Read Committed

Repeatable read Repeatable read Not Supported Repeatable Read

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

各个独立级别的含义请见表18.12

 

3. TDatabase的关键方法

  StartTransaction方法

  StartTransartion方法在由TaransIsolation属性指定的独立级别下开始事务控制。如果在一个事务已被激活的情况下调用该方法,Delphi将引发异常。

调用了该方法后,对数据库所做的修改一直由数据库服务器维持到调用Commmit方法提交数据或调用Rollback方法取消修改为止。只有当联接数据库服务器时,才能调用该方法。

  ⑵ Rollback方法

  Rollback方法返转当前事务控制,并且取消自最近一次调用StartTransaction以来对数据库所做的所有修改。

  ⑶ Commit方法

  Commit方法提交当前事务控制,并且将自最近一次调用StartTransaction以来所有数据修改存入数据库。

4. TDatabaseOnLogin事件的处理

  OnLogin事件的触发条件是当联接SQL数据库的TDatabase部件被打开并且LoginPrompt属性为True。使用OnLogin事件处理过程可以在运行时设置注册参数。OnLogin 事件处理过程得到TDatabase的注册参数数组Params,并且使用Values属性改变这些参数。

  例如:

 

 LoginParams.Vaiues['SERVER NAME'] := 'MYSERVERNAME';

LoginParams.Values['USER NAME'] := 'MYUSERNAME';

LoginParams.Values[PASSWORD'] := 'MYAPSSWORD';

 

  当控制从OnLogin事件处理过程中返回时,应用程序用这些参数来建立联接。

  OnLogin事件处理过程的声明是这样的:

 

  TLoginEvent = procedure(Database: TDatabase; LoginParam: TStrings) of Object;

property OnLogin: TLoginEvent;

 

TLoginEvent类型是处理OnLogin事件的方法头。Database参数是要联接的数据库。LoginParamsTStrings类型的对象,包含用户名和口令,以及打开数据库时所用的其它参数。用户名是形如USER NAME = John.Doe的字符串,口令是形如PASSWORD = is_Password的字符串。当OnLogin事件处理过程被调用时应当在LoginParams中加入用户名和口令。

 

18.3.1.2 定制数据库服务器的注册参数

 

  大多数数据库服务器都包含限制数据库访问的安全特征。通常,在用户能访问数据库之前,服务器都要求注册的用户名和口令。

  如果服务器需要注册,在设计阶段,Delphi 会在你试图联接时提示你,诸如在会TTable部件描述数据库表名时。

  在缺省情况下,Delphi应用在打开数据库服务器的联接时,显示标准注册对话框。如果联接已建立,则注册对话框不会出现。

  可以用下列方法处理服务器注册:

1. TDatabase部件的LoginPrompt属性置为True。这样,当应用程序试图建立数据库联接时,标准注册对话框会打开。

   2. LoginPrompt属性置为False,在TDatabase部件的Params属性中包含用户名和口令参数。例如:

 

   USERNAME = SYSDBA

PASSWORD = mosterkey

 

但不推荐使用该方法,因为这会危害数据库安全

  3. 使用TDatabase部件的OnLogin事件设置注册参数。OnLogin事件得到TDatabase 注册参数数组的拷贝,并利用Values属性改变这些参数。如:

 

   LoginParams.Values['SERVER NAME'] := 'MYSERVERNAME';

   LoginParams.Values['USER NAME'] := 'MYUERNAME';

   LoginParams.Values['PASSWORD'] := 'MYPASSWORD';

 

  当控制从数据库注册事件处理过程中返回时,这些参数被用来建立联接。

 

18.3.1.3 建立应用程序特定的别名

 

  TDatabaseAliases描述了数据库表的位置和数据库服务器的联接参数。通常都是在Delphi之外,运用BDE配置工具(BDECFG32.EXE)创建别名,并且别名被存在BDE 配置文件IDAPI32.CFG中。

  用户也可以用TDatabase创建只在应用程序中可用的别名,用TDatabase 创建的别名不会加进BDE配置文件中。任何DataSet部件可通过描述DatabaseName 属性来使用这些别名。为了定制这些局部别名的参数,用鼠标左键双击TDatabase部件或从TDatabase部件中选择Database EditorDelphi就会打开数据库属性编辑器(Database Properties Editor)

 

18.3.1.4 控制数据库的联接

 

  TDatabase部件的Connected属性,指示TDatabase部件是否建立与数据库服务器的联接。当应用程序打开数据库中的表时,Connected被设置为True。将Connected 设为True就建立了数据库的联接。

  1. 保持数据库联接

  TDatabaseKeepConnection属性描述当没有数据库表打开时是否要与保持数据库的联接。

  如果应用程序需要在单个数据库中多次打开关闭多个表时,将KeepConnection 置为True能使应用程序具备更好的性能。

  当KeepConnectionTrue时,即使没有表打开,应用程序也能保持数据库的联接。那么就能重复打开和关闭数据库表而不需每次进行联接注册。

  2. 使用TSesstion控制联接

 TSesstion部件有一个面向整个应用程序的KeepConnections属性。如果Session.KeepConnectionsTrue,那么用于所有TDatabase部件的数据库联接都是持久的。

  TSession为应用程序提供数据库联接的全局控制。TSession中的Databases 属性是Session中所有活跃数据库组成的数组,DatabasesCount属性描述活跃数据库的数目。

  3. 描述NetPrivate目录

  TSessionNetFileDir属性描述BDE网络控制目录的路径。TSessionPrivateDir属性描述存储诸述处理局部SQL表达式的临时文件的目录的路径。

 

18.3.1.5 获取数据库信息

 

  TSession拥有许多让用户获取数据库有关的信息,每个方法都以TStringList 部件作为传入参数,并将信息返回TStringList中。

  1. GetAliasNames方法

  声明:procedure GetAliasNames(List: TStringList);

  GetAliasNames方法消除List中的参数,并将所有已定义的BDE别名的名字写入List。应用程序生成的别名不包括在内。

  2. GetAliasParams方法

  声明:procedure GetAliasParams(const AliasName: String; List: TStringList);

GetAliasParams方法清除List的内容,并将BDE别名为AliaName的参数写入List

  3. GetDatabaseNames方法

  声明:procedure GetDatabaseNames(List: TStrings);

GetDatabaseNames方法清除List的内容并将所有BDE别名和应用程序定义的别名的名字写入List

4. GetDriverNames方法

  声明:procedure GetDriverNames(List: TStrings);

  GetDriverNames方法清除List中的内容,并将BDE当前安装的驱动程序名写入List

  5. GetDriverParams方法

  声明:procedure GetDriverParams(const DriverName: String; List: TStrings);

  GetDriverParams方法消除List中的内容,并将名为DriveName驱动程序缺省参数写入List

  6. GetTableNames方法

  声明:procedure GetTableNames(const DatabaseName, Pattern: Strings;

Extensions, SystemTable: Boolean; List: TStrings);

  GetTableNames方法消除List中的内容,并将名为DatabaseName的数据库中的所有表的名字写入ListPattern参数将限制表名。对于SQL服务器,将SystemeTables设为True将获取系统表和用户表。对非SQL数据库,将Extensions设为True将在表名中包含扩展名。

 

18.3.2 处理Client/Server事务控制

 

  使用隐式控制和显示控制的数据库应用中有两种方法管理事务控制:

 ● 运用TDatabase部件的属性和方法进行显式控制

  运用TQuery部件的传递式SQL控制事务

 

  Delphi还支持ParadoxdBASE表的局部事务处理

 

18.3.2.1 事务控制概述

 

  当用Delphi创建数据库应用时,Delphi提供了用为所有数据库访问的事务控制。

  事务是这样一组操作,在被提交前,它们对一个或多个数据库的操作,必须全部执行成功。如果其中一个操作失败,则所有操作失败,即事务具有原子性。

  即使发生硬件失败,事务也要保证数据库一致性。当允许多用户并发访问时,事务还要维持数据完整性。

  例如:一个应用程序可能更新ORDERS表以指明接受购买某一项目的定单,那么也要更新INNENTORY表以反映库存的减少。如果在第一个更新之后,第二个更新之前发生硬件错误,数据库就会处于不一致状态,因为库存情况没有反映定单情况。在事务控制下,两个表达式将在同一时间提交,如果其中一个表达式失败,则被返转(Rolled Back)

 

18.3.2.2 使用隐式控制

 

  在缺省情况下,Delphi通过BDE为应用程序提供隐式事务控制。当应用程序处于隐式事务控制时DelphiDataSet中的写每个记录进行隐式事务控制。它提交每一个独立的写操作,如PostAppend Record

  使用隐式事务控制是容易的,它保证最小的记录更新冲突和数据库的一致性视图。另一方面,因为写入数据库的数据的每一行都要进行事务控制, 所以隐式事务控制将导致网络过忙和应用程序性能下降。

  如果采用显式事务控制,就能选择最有效的时机来开始、提交和终止事务,特别是在开发多用户环境下的客户应用程序运行访问远程SQL服务器,就更应该采用显式控制。

 

18.3.2.3 使用显式事务控制

 

  有两种协作又独立的方式可运用于Delphi数据库应用的事务控制:

  ● 使用TDatabase部件的方法和属性

  ● 使用TQuery部件中的传递式SQL。这种方式只有在Delphi Client/Server Suite版中才有效,SQL LinksSQL表达式直接传给过程SQLODBC服务器

 

  使用TDatabase部件的方法和属性的好处是提供了清晰的、轻便的、与特定数据库或服务器无关的应用能力。

  使用传递式SQL的主要好处在于可以运用特定服务器的先进事务管理能力。

  1. 使用TDatabase的方法和属性

  下表中列出了TDatabase部件中用于事务管理的方法和属性以及它们的使用方法:

 

18.11 TDatabase用于事务显式控制的方法表

  ━━━━━━━━━━━━━━━━━━━━━━━━

   方法或属性     

  ────────────────────────

  Commit 提交数据的修改并终止事务

  Rollback 取消数据的修改并终止事务

  StartTransaction 开始一个事务

  TransIsolation 表述事务的独立性级别

  ━━━━━━━━━━━━━━━━━━━━━━━━

 

  StartTransactionCommitRollback是供应用程序在运行时调用开始事务,控制事务并且保存或放弃所做数据修改的方法。

  TransIsolationTDatabase部件的用于控制作用于相同表的不同事务之间如何交互的属性。

  ⑴ 开始一个事务

  当你开始一个事务时,后来的所有读写数据库的表达式都发生在那次事务的环境中。每个表达式都是其中一部分。任何表达式所做的修改,要么成功地提交给数据库,要么每一个修改都被取消。考虑一个在ATM上的银行传输问题。当顾客决定将钱从存款帐户转到支付帐户时,在银行数据库记录上必须发生两个修改:

  ● 存款帐户必须记入借方

  ● 支付帐户必须记入贷方

 

  如果出于某种原因,其中的一个操作不能被完成,那么任何一个操作都不应该发生。因为这些操作是相关的,它们应该发生在同一个事务中。

  为了开始Delphi应用程序中的一个事务,需要调用TDatabase部件中的StartTransaction方法:

 

  DatabaseInterBase.StartTransaction;

 

此后的所有数据操作都发生在最近一个事务的环境中,直到该次事务通过调用CommitRollback显式地终止为止。

  那么,应当将事务保持多久呢?理想状态下,只要需要,多久都行。事务的活跃状态越长,同时访问数据库的用户越多,在你的事务的生命其中,更多的并发、同时的事务开始和终止,于是当试图提交修改时,与其它事务冲突的可能性更大。

  ⑵ 提交一个事务

  为了做永久性修改,事务必须使用TDatabase部件的Commit方法提交。执行提交表达式将保存数据库的修改并终止事务。例如,下列表达式将终止在上例中开始的事务:

 

  DatabaseInterBase.Commit

 

  Commit的调用应当置于tryexcept表达式中。如果一个事务不能成功提交,你就能处理错误,并重试操作。

  ⑶ 返转一个事务

  为了取消数据库修改,必须用Rollback方法返转一个事务。Rollback 复原一个事务的修改,并终止事务,例如:下列表达式将返转一个事务:

 DatabaseInterBase.Rollback;

 

Rollback通常发生在:

  ● 异常处理代码

 ● 按钮或菜单事件代码,如用户点按了Cancel按钮

 

  ⑷ 使用TransIsolation属性

  TransIsolation属性描述TDatabase部件事务的独立级别,事务的独立级别决定了事务与其它作用于相同表的事务是如何相互作用的。在改变或设置TransIsolation 的值之前,应当相当熟悉Delphi中的事务和事务管理。

  TransIsolation的缺省值是tiReadCommitted。下表中总结了TransIsolation的可能值并描述了它们的含义:

 

18.12 TransIsolation属性值的含义

 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   独立级别         含

──────────────────────────────────────

  tiDirtyRead 允许读由其它同时事务写入数据库的未提交的修改。未提交的

             修改不是永久性的,可能在任何时候被复原。 在这个级别你

             的事务与其它事务所做的修改具有最低独立度。

  tiReadCommitted 只允许读由其它同时事务提交的数据库修改。这是缺省的独

             立级别。

  tiRepeatableRead 允许单个的数据库读事务无法看见其它同时事务对相同数据做

的修改。这个独立级别保证了你的事务一次读一个记录,记录

的视图不会改变, 在这个级别你的事务与其它事务做的修改完

全独立。

 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

  各种数据库服务器不同程度地支持这些独立级别,有的根本不支持。 如果请求的隔离级别不被服务器支持,Delphi将采用更高的独立级别。各种服务器支持的独立级别请参见表18.10

如果应用程序使用ODBC与服务器交互,ODBC驱动程序必须支持独立级别。

  2. 使用传递式SQL

  为了能使用传递式SQL控制事物,必须:

  使用Delphi Client/Server Suite

安装正确的SQL Links驱动程序

  正确配置网络协议

  访问远程服务器上数据库的能力

  BDE配置工具将SQLPASSTHROUGH MODE设置为NOT SHARED

 

通过传递式SQL,你可以使用TQueryTStoredProc、或TUpdateSQL部件直接发送一个SQL事务控制表达式给远程数据库服务器;BDE本身并不处理SQL表达式,采用传递式SQL可使用户直接获得SQL服务器提供了事务控制优点,尤其是当那些控制是非标准的时。

  SQL PASS THROUGHMODE 描述BDE和传递式SQL是否共享相同的数据库联接。在大多数情况下,SQLPASSTHROUGHMODE被设置SHARED AUTOCOMMIT。然而,如果你想将SQL事务控制传递给服务器,你就必须用BDE配置工具,将BDESQLPASSTHROUGHMODE 设置为NOT SHARED。此外,还必须为传递SQL事务控制表达式的TQuery部件建立独立的TDatabase 部件。

  3. 使用本地事务

  BDE还支持ParadoxdBASE上的本地事务。从代码角度而言,在本地事务和远程数据库服务器的事务之间没有什么差别。

  当作用于本地数据库表的事务开始时,更新操作被记录在日志中,每个日志记录包含旧的记录缓冲区。当事务处于活跃状态,更新的记录被锁定,直到事务被提交或返转,在返转过程中,旧的记录被应用于将更新的记录恢复到原先的状态。

 

18.3.3 使用存储过程

 

18.3.3.1 TStoredProc部件概述

 

  存储过程是以数据库服务器为基础的接受输入参数,并将结果返回给应用程序的一段程序。TStoredProc部件操作远程服务器上的数据库中的存储过程。存储过程是一连串表达式的集合,作为服务器的一部分存储。存储过程在服务器上执行一系列重复性的与数据库相关的任务,并将结果传给客户应用程序,如Delphi数据库应用程序。

TStaredProc部件使Delphi数据库应用程序能执行服务器上的存储过程。

  通常,作用于数据库表中大量记录并且使用统计或数学函数的操作都是存储过程的首选对象。通过将这些重复计算任务转移到服务器,可以提高数据库应用程序的性能。

  ● 充分利用服务器的处理能力和速度

 ● 减少网络传输的数量

 

  例如,考虑一个需要计算单个值的应用程序,在大批记录中的标准差值。如果在Delphi应用程序中执行这项功能就必须从服务器中得到所有在计算中用到的记录,这必将导致网络拥塞。因为应用程序所需的只是代表标准差的最终返回值。因此,由服务器上的存储过程来读数据,执行计算和将值传给应用程序将更有效。

  1. TSoredProc的关键属性

  ⑴ DatabaseName属性

  DatabaseName属性描述要访问的数据库的名字。该属性可以为:

  ● 已定义的BDE别名

  ● 本地型数据库的目录

  ● Local InterBase服务器的目录路径和文件名

  ● TDatabase定义的应用程序别名

 

  在改变DatabaseName之前要使用Close方法将Dataset部件置为非活跃状态。

  ⑵ StoredProcName属性

  StoredProcName属性表示服务器上的存储过程名。Oracle服务器允许多个具有相同名字的存储过程。因此要设置Overload属性来描述执行在Oracle服务器上的存储过程名。

  ⑶ Overload属性

  Oracle服务器允许Oracle软件包中存储过程的重载。就是说具有相同名字的不同过程,设置Overload属性用来描述执行在Oracle服务器上的存储过程。如果Overload值为零,则假定没有重载,如果Overload1,则Delphi执行具有同名的第一个存储过程;如果值为2,则执行第二个存储过程。

  ⑷ Params属性

  Params属性包含传给存储过程的参数。

  2. 关键方法

  ⑴ ParamByName方法

  声明:function ParamByName(const Value: String): TParam;

ParamByName方法返回Params属性中具有名为Value的元素值。一般用该方法在动态查询中给参数赋值。

  ⑵ Prepare方法

  PrePare方法准备要执行的存储过程,这允许服务器载入存储过程,否则准备处理异常。

  ⑶ ExecProc方法

  ExecProc方法执行服务器上的存储过程。

  ⑷ Open方法

  Open方法打开DataSet部件,并将其置于浏览状态。这相当于将Active属性置为True。对于TStoredProc如果存储过程返回一个结果集,则使用Open执行存储过程。如果存储过程返回单行,早使用ExecProc执行存储过程。

 

18.3.3.2 TStoreProc使用方法

 

  1. 建立一个StoredProc部件

  为数据库服务器上的存储过程建立一个TStoredProc部件的步骤如下:

  ⑴ Component PaletteData Access页选择TStoredProc部件放在数据模块上。

  ⑵ TStoredProc部件的DatabaseName属性设置为存储过程所在的数据库名。

DatabaseName必须是BDE别名。

  ⑶ TStoredProc部件的StoredProcName属性设为所用的存储过程名,或者从下拉式

列表框中选择。

  ⑷ TStoredProc部件的Params属性中描述输入参数。可以使用参数编辑器来设置输

入参数。参数编辑器也可让用户察看存储过程返回给应用程序的值。

 

  2. 设置存储过程的输入参数,察看输出结果参数

  许多存储过程需要给它们传入一系列的输入参数,以确定处理什么和怎样处理,在Params属性中描述这些参数。所描述的输入参数的顺序是很重要的,它由服务器上的存储过程来确定。在设计时,最容易和最安全的方法是激活TStoredProc参数编辑器,编辑输入参数。参数编辑器以正确的次序列出输入参数,让你给它们赋值。

  要激活TStoredProc的参数编辑器:

选择TStoredProc部件。

  按鼠标右键激活加速菜单(Speed Menu)

选择Define Parameters

 

参数名列表框显示过程的所有输入,输出和结果参数。有关输入、输出参数的信息从服务器中获得。对于某些服务器而方,参数信息是不可访问的,如Sybase,在这种情况下,列表框是空的,因此必须自己按过程要求的顺序增加输入输出参数。

  参数类型复选框中描述所选的参数是输入、输出,还是结果参数。如果服务器支持参数可以既是输入又是输出。如果在列表框中增添参数,就必须设置参数类型。

  数据类型复选框,列出列表框中所选参数的数据类型。如果给列表框真善美参数,必须设置数据类型。

  在值编辑框中给输入参数赋值。

  如果服务器不传递存储过程信息给Delphi,则可以用Add按钮给存储过程增添参数。Delete按钮则是将增添的参数删除,Clear按钮将清除列表框中所有参数。

  设置完参数后,选择OK按钮。

 

  3. 在运行时建立参数和参数值

  在运行时建立参数,可直接访问Params属性。Params属性是参数字符串的数组。例如,下列代码将编辑框的文本赋给数组的第一个字串:

 

  StaredProc1.Params[0].Asstring := Edit1.Text

 

  也能够用ParamsByName方法通过名字访问参数:

 

  StoredProc1.ParamsByName('Company') Asstring := Edit1.Text;

 

  4. 准备和执行存储过程

  要使用存储过程还必须准备并执行它。可以有两种方式准备一个存储过程:

  在设计时,通过选择参数编辑器的OK按钮

  在运行时,通过调用TStoredProcPrepare方法

 

  例如,下面的代码准备存储过程的执行:

 

  StoredProc1.Prepare;

 

  要执行准备好的存储过程,调用TStroedProc部件的ExecProc方法。下列代码演示了准备和执行存储过程:

 

   StoredProc1.Params[0] Asstring := Edit1.Text;

StoredProc1.prepare;

StoredProc1.ExecProc;

 

  当你执行一个存储过程,它返回输出参数或结果集,有两种可能的返回类型:单个返回,如单值或值集,和一群结果集,返回很多值。

  5. 访问输出参数和结果集

  存储过程在输出参数数组中返回值。如果服务器支持返回值可以是单个结果或者结果集。

  在运行时访问存储过程的输出参数,可以索引Params属性或者用ParamByName方法访问这些值。下列表达式都用输出参数设置了编辑框的值:

 

  Edit1.Text := StoredProc1.Params[6].AsString;

   Edit1.Text := StoredProc1.ParamsByName('Contact').AsString;

 

  如果存储过程返回结果集,则用标准数据相关控制访问和显示值会更有用。

  在某些服务器上如Sybase,存储过程能象查询语句那样返回结果集,应用程序可以使用数据相关控制一显示这些存储过程的输出。

  用数据相关控制显示存储过程返回结果的方法如下:

  ① DataSource部件放在数据模块上。

 ② DataSource部件的DataSet属性设置为接收数据的TStoredProc部件的名字。

  ③ 将数据相关控制的DataSource属性设为DataSource部件的名字。 

  这样,当用于TStoredProc部件和Active属性为True时,数据相关控制就能显示从存储过程返回的结果。 

 

18.3.4 从开发平台到服务器的向上适化

 

18.3.4.1 适化概述 

 

  所谓适化就是将桌面应用转化为Client/Server应用。

  适化是一个很复杂的主题,这里不详细讲述。本节将介绍适化Delphi 应用程序中最重要的方面。

  适化的主要方面有:

  ● 将数据库从桌面平台到服务器的适化

  将应用程序转化为Client/Server的适化

 

  适化还需要实现从桌面环境到Client/Server环境的转化。

  桌面数据库和SQL服务器数据库在许多方面有不同之处。例如:

 ● 桌面数据库用于同一时刻单用户的访问,而服务器用于多用户访问

 ● 桌面数据库是面向记录的,而服务器是面向集合的

  桌面数据库将每个表存储在独立的文件中, 而服务器将所有的表存储在数据库中Client/Server应用必须解决更新的问题,最复杂的是联接、网络和事务控制

 

18.3.4.2 适化数据库

 

  适化数据库包含下列步骤:

  ● 在桌面数据库结构的基础上,定义服务器上的元数据

  将数据从桌面转化到服务器中

 ● 解决下列问题:

  数据类型差异

   ● 数据安全性和完整性

  事务控制

   数据访问权

   ● 数据合法性

   ● 锁定

 

 Delphi提供了两种方法适化一个数据库。

  使用Database Desktop工具,选择菜单Tools/Utilities/Copy to命令将数据库表从桌面方式拷贝到SQL格式

建立应用TBatchMove部件的应用程序

 

  这两种方法都可以将表结构和数据从桌面数据源转化到服务器上。依靠这些数据库,可能需要改变结果表。例如,可能想进行不同数据类型的映射。

  也可以将下列特征加入数据库:

完整性约束

索引

  检测约束

存储过程和触发器

  其它服务器特征

 

  如果用SQL脚本和服务器数据定义工具定义元数据会更有效。然后用前面介绍的两种方法转移数据。因为如果是手工定义数据库表,Database DesktopTBatchMove 部件将只拷贝数据。

 

18.3.4.3 适化应用程序

 

  在理论上,设计用来访问局部数据的Delphi应用程序做很少的修改就可以访问远程服务器上的数据。如果在服务器上定义适合的数据源,你就能将应用程序指向访问它,这只需简单地改变应用程序中TTableTQuery部件的DatabaseName属性。

  实际上,在访问局部和过程数据源之间有许多重要的不同之处。Client/Server应用程序必须解决大量的在桌面应用中所没有的问题。

  任何Delphi应用程序都能用TTableTQuery部件访问数据。桌面应用程序通常都是使用TTable部件。当适化到SQL服务器上时,用TQuery会更有效,如果应用程序要检索大量记录,则TQuery部件要略胜一筹。

  如果应用程序使用统计或数学函数,那么在服务器上通过存储过程执行这些函数会更有效。因为存储过程执行更快,使用存储过程还可以减少网络负载,特别是大量行数据的函数。

  例如,计算大量记录的标准差:

  ● 如果该函数在客户端执行,所有的值从服务器上检索出来并送到客户端,导致网络拥塞

  ● 如果该函数在服务器端执行,则应用程序只需要服务器上的答案

 

 

 

 

 

 

18.4 Delphi客户/服务器应用实例分析

 

  本节中采用的实例是Delphi2.0数据库的例子CSDEMOCSDEMODelphi客户/服务器编程的示例程序,它采用的数据库服务器是Local InterBase Server

CSDEMO较好地示范了BDE环境的配置,InterBASE Server高级功能应用,SQL服务器联接,触发器应用、存储过程编程和事务控制技术等,具有较高的参考价值。本节讲述下列内容:

  数据库环境介绍

  ● TDatabase的应用

 ● 不同数据库表的切换

  触发器编程

  ● 存储过程编程

 ● 事务控制应用

 

18.4.1 数据库环境介绍

 

  本例中采用的数据库服务器是Local InterBase ServerLocal InterBaseInterBase Server的单用户版32位、兼容ANSI SQLLocal InterBase支持客户/服务器应用在单机上的开发和测试,并且可以很容易地适化到InterBase Server上。因此,开发客户/服务器应用采用Local InterBase作为原型开发环境是很方便的。

 

18.4.1.1 IBLOCALBDE参数

 

  本例中的SQL数据库是IBLOCAL。它是由BDE配置工具(BDECFG32.EXE)设置参数值。它的各项参数值列于下表:

 

18.13 IBLOCAL的各项参数值

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

────────────────────────────────────

TYPE INTRBASE

PATH

SERVER NAME C:\INTRBASE\EXAMPLES\EMPLOYEE.GDB

USER NAME SYSDBA

OPEN MODE READ/WRITE

SCHEMA CACHE SIZE 8

LANGDRIVER

SQLQRYMODE

SQLPASSTHRU MODE SHARED AUTOCOMMIT

SCHEMA CHCHE TIME -1

MAX ROWS -1

BATCH COUNT 200

ENABLE SCHEMA CACHE FALSE

SCHEMA CACHE DIR

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

18.4.1.2 数据库结构介绍

 

 IBLOCAL数据库的结构都是由InterBase服务器工具交互式SQL工具(ISQL)定义的。

  用ISQL定义数据库,首先要用Create Database命令建立数据库,建立的新数据库一般是以GDB为扩展名。建立好后,就可以用SQL语言定义数据库表,例如建立EMPLOYEE表的SQL语句如下:

 

定义域名数据类型:

 

CREATE DOMAIN FIRSTNAME AS VARCHAR(15);

CREATE DOMAIN LASTNAME AS VARCHAR(20);

CREATE DOMAIN COUNTRYNAME AS VARCHAR(15);

CREATE DOMAIN EMPNO AS SMALLINT;

CREATE DOMAIN DEPTNO AS CHAR(3)

CHECK (VALUE = '000' OR (VALUE > '0' AND VALUE <= '999') OR VALUE IS NULL);

CREATE DOMAIN JOBCODE AS VARCHAR(5)

CHECK (VALUE > '99999');

CREATE DOMAIN JOBGRADE AS SMALLINT

CHECK (VALUE BETWEEN 0 AND 6);

CREATE DOMAIN SALARY AS NUMERIC(15, 2)

DEFAULT 0

CHECK (VALUE > 0);

 

建立EMPLOYEE表:

 

CREATE TABLE EMPLOYEE (EMP_NO EMPNO NOT NULL,

FIRST_NAME FIRSTNAME NOT NULL,

LAST_NAME LASTNAME NOT NULL,

PHONE_EXT VARCHAR(4),

HIRE_DATE DATE DEFAULT 'NOW' NOT NULL,

DEPT_NO DEPTNO NOT NULL,

JOB_CODE JOBCODE NOT NULL,

JOB_GRADE JOBGRADE NOT NULL,

JOB_COUNTRY COUNTRYNAME NOT NULL,

SALARY SALARY NOT NULL,

FULL_NAME COMPUTED BY (last_name || ', ' || first_name),

PRIMARY KEY (EMP_NO));

 

  CHECK语句是给数据库字段取值范围加约束条件。PRIMARY_KEY语句是给表建立关键字索引。

  如法炮制,就可以定义IBLOCAL中的所有表。

  IBLOCAL中的表包括:

 

EMPLOYEE CUSTOMER DEPARTMENT EMPLOYEE_PROJECT

PROJECT SALES SALARY_HISCORY

 

各数据库表中的内容如下:

 

18.14 EmployeeDemoDB中各数据库表的内容

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━

    数据库表名        表中内容

   ───────────────────────────

     EMPLOYEE 雇员信息

   CUSTOMER 客户信息

DEPARTMENT 部门信息

EMPLOYEE_PROJECT 雇员负责的工程

PROJECT 工程信息

SALES 销售信息

SALARY_HISTORY 雇员薪水调整的历史信息

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

每个数据库表中都定义了关键字段。关于数据库表中的字段名、类型、大小,这里不再赘述。

 

18.4.2 应用程序分析

 

18.4.2.1 TDatabase部件的使用

 

  CSDEMO程序中定义了一个数据库模块部件——TDmEmployee,它是继承于TDataModuleTDataModule是在Delphi2.0中才出现的专门放置数据访问部件(TDatabaseTTableTQuery)的框架。其它涉及数据库访问的窗体,只要在uses语句中插入数据库模块所在的库单元,该窗体上的数据库部件就可引用相应的数据库访问部件。

  在TDmEmployee中定义了一个TDatabase类型的部件──EmployeeDatabaseEmployeeDatagase的主要属性及属性值如下:

 

18.15 EmployeeDatabase部件主要属性的取值

   ━━━━━━━━━━━━━━━━━━━━━━━

    属性        属性值

   ───────────────────────

    AliasName IBLOCAL

DatabaseName EmployeeDemoDB

KeepConnection True

LoginPrompt False

TransIsolation tiReadCommitted

Params USERNAME = SYSDBA

PASSWORD = masterkey

Connected True

  ━━━━━━━━━━━━━━━━━━━━━━━

 

AliasName属性所指定的IBLOCAL,必须已经在BDE中配置好,DatabaseName属性指定要使用的数据库名,该数据库名是由应用程序自己定义的,因此不反应到BDE中,该属性值被TTableTQueryDataSet部件引用,并且出现在DataSet部件的DatabaseName 下拉式列表框中。本例中的“EmployeeDemoDB”,被EmployeeTableSalesTable等所有DataSet部件引用。

ConnectedTrue表明,应用程序与数据库将保持联接。

KeepConnection属性为True,表明多次打开和关闭EmployeeDemoDB数据库中的任意表,应用程序将始终与数据库保持联接,这省却了重复注册的开销。

LoginPrompt 属性为False,表明应用程序自动处理与数据库的联接注册,因此,Params属性中定义了注册的用户名和口令:

 

  USERNAME = SYSDBA

PASSWORD = masterkey

 

TransIsolation属性为tiReadCommitted表明,如果存在多个同时事务,则某一事务只允许读由其它事务提交了的数据。

  程序中EmployeeDatabase的应用还与事务控制等有关。下文中会介绍这方面的内容。

 

18.4.2.2 不同数据库表的切换

 

  在许多数据库应用中都要在不同数据库表之间相互切换,以响应用户输入条件或系统状态的变化。这时,往往需要特别的处理,例如改变光标形状或隐藏数据改变等,尤其是在客户/服务器应用程序中。因为是用SQL语句访问远程数据库,有时还要在服务器端执行计算任务,所以客户端的数据变化会有一定的间隔,因此应该让用户明白发生了什么。下面是CSDEMO在数据库表切换时的处理办法:

 

procedure TFrmViewDemo.ShowTable( ATable: string );

begin

Screen.Cursor := crHourglass; { 向用户提示当前操作状态 }

VaryingTable.DisableControls; { 隐藏数据变化 }

VaryingTable.Active := FALSE; { 关闭原来的数据库表 }

VaryingTable.TableName := ATable; { 更新数据库表名 }

VaryingTable.Open; { 打开数据库表 }

VaryingTable.EnableControls; { 显示所作的修改 }

Screen.Cursor := crDefault; { 重新设置光标形状 }

end;

 

  crHourglass型光标表明正在执行SQL查询。DisableControlsEnableControls的作用是隐藏和显示数据变化。

 

18.4.2.3 InterBase触发器(Trigger)的应用

 

  在CSDEMO应用程序中,演示触发器应用的窗体是TFromTriggerDemo

 

 

在该窗体中包含两个TDBGrid对象。DBGrid1显示EmployeeTable中的数据,DBGrid2显示SalaryHistoryTable中的数据。它们的主要属性及属性值如下:

 

18.16 EmlpoyeeTable部件主要属性的取值

   ━━━━━━━━━━━━━━━━━━━━━

    属 性      

   ─────────────────────

     DatabaseName EmployeeDemoDB

IndexFieldName Emp_No

TableName EMPLOYEE

━━━━━━━━━━━━━━━━━━━━━

 

18.17 SalaryHistoryTable部件主要属性的取值

   ━━━━━━━━━━━━━━━━━━━━━

   属 性       属

    ─────────────────────

    DatabaseName EmployeeDemoDB

IndexFieldName Emp_No

     MasterFields Emp_No

MasterSource EmployeeSource

TableName SALARY_HISTORY

   ━━━━━━━━━━━━━━━━━━━━━

 

  这两个表之间存在两种关系:

  ● 连接关系

EmployeeTable的记录变化时,SalaryHistoryTable的数据要作相应的变化。这种连接关系是通过索引来实现的。

  ● 数据一致性

EmployeeTable中的Salary字段的值作修改必须反映到SalaryHistoryTable中,SalaryHistoryTable维护的是Salary变化的历史信息。这种数据一致性要求在本程序中是通过触发器实现的。

  触发器是在SQL服务器端执行的一段程序,它在服务器端被触发执行完成一定的数据计算任务。

  下面是InterBase服务器上与Employee表相关的触发器程序:

 

Triggers on Table EMPLOYEE:

SAVE_SALARY_CHANGE, Sequence: 0, Type: AFTER UPDATE, Active AS

BEGIN

IF (old.salary <> new.salary) THEN

INSERT INTO salary_history

(emp_no, change_date, updater_id, old_salary, percent_change)

VALUES (

old.emp_no,

'now',

user,

old.salary,

(new.salary - old.salary) * 100 / old.salary);

END

 

  因为触发器是相应于EMPLOYEE表上的数据修改由服务器自动触发执行的,所以在客户应用程序上没有显式的调用。在客户端有打开并显示数据库表内容的程序和当SALARY_HISTORY表中数据变化时的更新显示的操作。

 

procedure TFrmTriggerDemo.FormShow(Sender: TObject);

begin

DmEmployee.EmployeeTable.Open;

DmEmployee.SalaryHistoryTable.Open;

end;

 

procedure TDmEmployee.EmployeeTableAfterPost(DataSet: TDataSet);

begin

{ 一个雇员的薪水变化将触发薪水调整历史记录的变化,

因此,如果SalaryHistory打开的话,就需要更新显示 }

with SalaryHistoryTable do if Active then Refresh;

end;

 

18.4.2.4 存储过程编程

 

  存储过程也是SQL服务器上的一段程序,它接收输入参数,在服务器端执行,并将结果返回客户端,存储过程是必须在客户应用程序中显式调用的。

  对于数据库表中大量记录的统计和函数计算,存储过程是很有用,这样可以将重复性计算任务转换到服务器,提高数据库应用的性能。

  Delphi中有两个部件能操作远程数据库服务器上的存储过程:TQueryTStoredProc

1. TQuery的存储过程编程

CSDEMO中演示用TQuery调用存储过程的窗体是TFrmQueryProc 

 

  TFrmQueryProc中有两个TDBGrid 部件。DBGrid1显示EmployeeTable中的数据。DBGrid2显示Project表中的数据。使用存储过程的TQuery部件名为EmployeeProjectsQuery,它的作用是建立Employee 表和Project 表的连接,以实现当DBGrid1中记录改变时,DBGrid2中的数据作相应的改变。具体的连接任务是由服务器上的存储过程Get_Emp_Proj完成。下面是Get_Emp_Proj的程序:

 

PROCEDURE Get_Emp_Proj

BEGIN

FOR SELECT proj_id

FROM employee_project

WHERE emp_no = :emp_no

INTO :proj_id

DO

SUSPEND;

END

 

EMP_NO INPUT SMALLINT

PROJ_ID OUTPUT CHAR(5)

 

  该过程带两个参数:

  EMP_NO是输入参数,类型是SMALLINT.

PROJ_ID是输出参数,类型是CHAR(5)

 

  相应地,EmployeeProjectsQuery的主要属性如下:

 

18. 18 EmployeeProjectsQuery部件主要属性的取值

━━━━━━━━━━━━━━━━━━━━━━━━━━

   属 性       属

   ──────────────────────────

    DatabaseName EmployeeDemoDB

Params EMP_No(输入参数,Smallint类型)

SQL Select * from

Get_Emp_Proj(:EMP_NO)

━━━━━━━━━━━━━━━━━━━━━━━━━━

 

TQuery部件是在SQL语句中直接调用存储过程。

  下面是客户端的程序:

 

procedure TFrmQueryProc.FormShow(Sender: TObject);

begin

DmEmployee.EmployeeTable.Open;

EmployeeSource.Enabled := True;

with EmployeeProjectsQuery do if not Active then Prepare;

end;

 

  用Prepare显式地准备SQL语句,虽非必须,但可以优化SQL的执行。

 

procedure TFrmQueryProc.EmployeeDataChange(Sender: TObject; Field: TField);

begin

EmployeeProjectsQuery.Close;

EmployeeProjectsQuery.Params[0].AsInteger :=

DmEmployee.EmployeeTableEmp_No.Value;

EmployeeProjectsQuery.Open;

 

WriteMsg('Employee ' + DmEmployee.EmployeeTableEmp_No.AsString +

' is assigned to ' + IntToStr(EmployeeProjectsQuery.RecordCount) +

' project(s).');

end;

 

  该事件处理过程与EmployeeSourceOnDataChange属性相联。用于当EmployeeTable数据记录变化时,修正存储过程的输入参数,并执行SQL语句。

  2. TStoredProc部件的存储过程编程

  TStoredProc Delphi 专门用来使用服务器存储过程的部件。CSDEMO 中演示用TStoredProc调用存储过程的窗体是TFrmExecPr

  在程序运行中,当按下ShipOrder按钮,要求对ORED_STA_TUS等字段的内容作修改以维护数据库的一致性。字段内容的修改任务由服务器上的存储过程SHIP_ORDER完成。SHIP_ORDE的程序如下:

 

PROCEDURE SHIP_ORDER

DECLARE VARIABLE ord_stat CHAR(7);

DECLARE VARIABLE hold_stat CHAR(1);

DECLARE VARIABLE cust_no INTEGER;

DECLARE VARIABLE any_po CHAR(8);

BEGIN

SELECT s.order_status, c.on_hold, c.cust_no

FROM sales s, customer c

WHERE po_number = :po_num

AND s.cust_no = c.cust_no

INTO :ord_stat, :hold_stat, :cust_no;

IF (ord_stat = "shipped") THEN

BEGIN

EXCEPTION order_already_shipped;

SUSPEND;

END

ELSE IF (hold_stat = "*") THEN

BEGIN

EXCEPTION customer_on_hold;

SUSPEND;

END

 

FOR SELECT po_number

FROM sales

WHERE cust_no = :cust_no

AND order_status = "shipped"

AND paid = "n"

AND ship_date < 'NOW' - 60

INTO :any_po

DO

BEGIN

EXCEPTION customer_check;

 

UPDATE customer

SET on_hold = "*"

WHERE cust_no = :cust_no;

 

SUSPEND;

END

 

UPDATE sales

SET order_status = "shipped", ship_date = 'NOW'

WHERE po_number = :po_num;

SUSPEND;

END

 

Parameters:

PO_NUM INPUT CHAR(8)

 

  该过程只带有一个输入参数:PO_NUM,类型是CHAR(8)

  在客户端使用该过程的TStoreProc部件是ShipOrderProc,其主要属性如下表:

 

18.19 ShipOrderProc部件主要属性的取值

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   属性名         

    ────────────────────────────

    DatabaseName EmployeeDemoDB

ParamBindMode pbByName

Params PO_NUM(输入参数,String类型)

StoredProcName SHIP_ORDER

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 

  客户端执行SHIP_ORDER的程序如下:

 

procedure TFrmExecProc.BtnShipOrderClick(Sender: TObject);

begin

with DmEmployee do

begin

ShipOrderProc.Params[0].AsString := SalesTable['PO_NUMBER'];

ShipOrderProc.ExecProc;

SalesTable.Refresh;

end;

end;

 

  当用户按ShipOrder按钮时,执行这段程序。程序中先准备输入参数,用ExecProc

法执行存储过程。调用SalesTable.Refresh方法刷新数据显示。

  在CSDEMO应用程序中另一个使用存储过程的TStoredProc部件是DeleteEmployeeProc。它完成的任务是删除Employee表中的记录,并修改所有相关的表, 以维护数据的一致性。其属性如下:

 

18.20 DeleteEmployeeProc部件主要属性的取值

  ━━━━━━━━━━━━━━━━━━━━━━━━━━

   属性名         

  ──────────────────────────

   DataBaseName EmployeeDemoDB

ParamBindMode PbByName

Params EMP_NUM(输入参数,整型)

StoredProcName DELETE_EMPLOYEE

━━━━━━━━━━━━━━━━━━━━━━━━━━

 

  存储过程DELETE_EMPLOYEE的程序如下:

 

PROCEDURE DELETE_EMPLOYEE

DECLARE VARIABLE any_sales INTEGER;

BEGIN

any_sales = 0;

SELECT count(po_number)

FROM sales

WHERE sales_rep = :emp_num

INTO :any_sales;

IF (any_sales > 0) THEN

BEGIN

EXCEPTION reassign_sales;

SUSPEND;

END

UPDATE department

SET mngr_no = NULL

WHERE mngr_no = :emp_num;

UPDATE project

SET team_leader = NULL

WHERE team_leader = :emp_num;

DELETE FROM employee_project

WHERE emp_no = :emp_num;

DELETE FROM salary_history

WHERE emp_no = :emp_num;

DELETE FROM employee

WHERE emp_no = :emp_num;

SUSPEND;

END

 

Parameters:

EMP_NUM INPUT INTEGER

 

  从上述存储过程的例子中,我们看到存储过程在维护服务器上的数据一致性方面有很强的能力,它节省了系统开销,提高了客户端的性能。

 

18.4.2.5 事务控制编程

 

  在客户/服务器应用程序中,事务控制是一项很重要的技术。它对于提高系统的可靠性,维护数据一致性有着重要的意义。

  Delphi中提供了事务的隐式和显式两种控制方法。其中显式控制的性能较高,下面介绍Delphi事务显式控制的编程方法。

  Delphi担当事务控制任务的部件是TDatabase TDatabase 用于事务控制的属性是TransIsolation,方法有StartTranstionCommitRollback。关于这些属性和方法作用和使用方法请参阅客户/服务器事务管理。

  在CSDEMOTDatabase 部件为EMployeeDatabase,其TransIsolation属性值为tiReadCommitted,意为如果存在多个同时事务访问数据库,则其中任一事务只能读其它事务提交的了数据。

  CSDEMO中演示事务控制的窗体是TFrmTransDemo

  DBGrid1中显示EmployeeTable中的内容。当窗口显示时,EmployeeDatabase开始一次事务控制并激活EmployeeTable

 

procedure TFrmTransDemo.FormShow(Sender: TObject);

begin

DmEmployee.EmployeeDatabase.StartTransaction;

DmEmployee.EmployeeTable.Open;

end;

 

当窗口被关闭或隐藏时,EmployeeDatabase提交事务:

 

procedure TFrmTransDemo.FormHide(Sender: TObject);

begin

DmEmployee.EmployeeDatabase.Commit;

end;

 

  窗口中有两个按钮BtnCommitEditsBtnUndoEdits。按下BtnCommitEdits按钮将提交当前事务,并开始新的事务控制并刷新数据。

 

procedure TFrmTransDemo.BtnCommitEditsClick(Sender: TObject);

begin

if DmEmployee.EmployeeDatabase.InTransaction and

(MessageDlg('Are you sure you want to commit your changes?',

mtConfirmation, [mbYes, mbNo], 0) = mrYes) then

begin

DmEmployee.EmployeeDatabase.Commit;

DmEmployee.EmployeeDatabase.StartTransaction;

DmEmployee.EmployeeTable.Refresh;

end else

MessageDlg('Can''t Commit Changes: No Transaction Active', mtError, [mbOk], 0);

end;

 

  按下BtnUndoEdits按钮将返转当前事物,恢复原来的数据,开始新的事务控制,并刷新数据的显示。

 

procedure TFrmTransDemo.BtnUndoEditsClick(Sender: TObject);

begin

if DmEmployee.EmployeeDatabase.InTransaction and

(MessageDlg('Are you sure you want to undo all changes made during the ' +

'current transaction?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then

begin

DmEmployee.EmployeeDatabase.Rollback;

DmEmployee.EmployeeDatabase.StartTransaction;

DmEmployee.EmployeeTable.Refresh;

end else

MessageDlg('Can''t Undo Edits: No Transaction Active', mtError, [mbOk], 0);

end;

 

posted on 2008-12-16 01:52  okwary  阅读(411)  评论(0编辑  收藏  举报
ggg