用Delphi开发数据库程序经验三则

用Delphi开发数据库程序经验三则,第1张

一 建立临时表 数据输入是开发数据库程序的必然环节 在Client/Server结构中 客户端可能要输入一批数据后 再向服务器的后台数据库提交 这就需要在本地(客户端)建立临时数据表来存储用户输入的数据 待提交后 清除本地表数据 这种方法的好处是 提高输入效率 减小网络负担

由于用户一次输入的数据量一般情况下较小(不会超过几百条记录) 所以临时表可以建立在内存中 这样处理速度较快 方法 使用查询控件(TQuery)第 步 在窗体上放上查询控件(TQuery) 设置好所连接的数据表 第 步 使 TQuery CachedUpdates=True;TQuery RequestLive=True;第 步 在原有的SQL语句后加入一条Where子语句 要求加入这条Where子语句后SQL查询结果为空 例如 SELECT Biolife ″Species No″ Category Common_Name Biolife ″Species Name″ Biolife ″Length (cm)″ Length_In Notes Graphic FROM ″biolife db″ Biolifewhere Biolife Category=′A′ and Biolife Category=′B′这样临时表就建立完成了

方法 使用代码创建临时表代码如下 function CreateTableInMemory(const AFieldDefs:TFieldDefs):TDataSet;var TempTable:TClientDataSet;begin TempTable:=nil; Result:=nil; if AFieldDefs<>nil then begin try TempTable:=TClientDataSet Create(Application); TempTable FieldDefs Assign(AFieldDefs); TempTable CreateDataSet; Result:=(TempTable as TDataSet); Except if TempTable<>nil then TempTable Free;

Result:=nil; raise;  end;end; end;

在程序中按如下方法使用 procedure TForm Button Click(Sender: TObject);var ADataSet:TDataSet;begin ADataSet:=TDataSet Create(Self); with ADataSet FieldDefs do begin Add(′Name′ ftString False); Add(′Value′ ftInteger False); end;

with DataSource do begin DataSet:=CreateTableInMemory(ADataSet FieldDefs); DataSet Open; end;

ADataSet Free;end;

临时表创建完成

方法 使用简单 但由于利用查询控件 清空数据时需要查询服务器后台数据库 所以速度稍慢 而且不适用于临时表中各个字段由数个数据表的字段拼凑而成的情况 方法 适用范围广 速度快 但需要编写代码 (代码中TFieldDefs的使用方法十分简单 见Delphi的联机帮助)

二 配置数据引擎(BDE SQL Link)有关数据库程序分发时 需要携带数据引擎(BDE SQL Link) 并且在客户端安装完程序后还需要配置数据引擎 如用户名(username) 密码(Password)等等 如果手工配置的话 工作量比较大(根据客户机数量而定) 而InstallShield For Delphi又好像没有这方面的选项 其实InstallShield For Delphi可以做到 在生成安装程序的目录里有一个* iwz的文本文件 只要在[IDAPI Alias]片段中手工加入即可 例如 [IDAPI Alias] usesname=SYSDBA password=masterkey 安装程序后数据引擎自动配置完毕

三 在InterBase数据库中使用函数 程序员可能在用InterBase作为后台数据库时 会为其提供的函数过少而感到不方便(只有四个) 无法方便地编写出复杂的存储过程 InterBase本身无法编写函数 但它可以使用外部函数(调用DLL中的函数) 下例中说明如何在InterBase 中声明SUBSTR函数 DECLARE EXTERNAL FUNCTION SUBSTR CSTRING( ) SMALLINT SMALLINT RETURNS CSTRING( ) ENTRY_POINT ″IB_UDF_substr″ MODULE_NAME ″ib_udf″

其中 MODULE_NAME为DLL的名称 ENTRY_POINT为函数名 声明后便可以使用 例如 select SUBSTR(country) from country

lishixinzhi/Article/program/Delphi/201311/8520

在数据库应用程序中 数据控件是经常要用到的 数据控件都是可视的 也就是说 如果修改了这些构件的属性 能在窗体上马上反映出来 如果这些构件的Enabled属性设为True并且数据集的Active属性也设为True 在设计期就可以看到数据

下面就来介绍一下这些控件的简单应用

指定一个数据源

数据控件必须通过TDataSource构件连接数据集 TDataSource构件扮演的角色实际上就是数据控件与数据集之间的桥梁 首先 把一个数据集构件放到窗体或数据模块上 设置它的DatabaseName属性指定要访问的数据库 设置它的TableName属性指定要访问的表 接着 把一个TDataSource构件放到窗体或数据模块上 设置它的DataSet属性指定数据集 然后 把一个数据控件放到窗体上 设置它的DataSource属性指定TDataSource构件 而这个TDataSource构件的DataSet属性已经指定了一个数据集 最后 设置数据控件的DataField属性指定要显示的字段 不过 对于TDBGrid TDBCtrlGrid和TDBNavigator构件来说 不需要设置DataField属性 因为这几个控件是以整个数据集为工作内容的

编辑和更新数据

除了TDBNavigator构件外 其他数据控件都是用来显示和编辑数据的 这里要介绍怎样编辑数据

要使用户能编辑数据 数据集必须进入dsEdit状态 如果TDataSource的AutoEdit属性设为False 用户不能直接编辑数据 除非程序调用Edit函数

要使用户能够在数据控件中修改数据 必须把数据控件的ReadOnly属性设为False 如果ReadOnly属性设为True 数据控件中显示的数据就是只读的 一般情况下 TDataSource构件的Enabled属性设为True 如果这个属性设为False 数据控件就无法显示数据 更不能修改数据

如果数据集构件的ReadOnly属性设为True 数据集就是只读的 用户在数据控件中所作的修改不能写到数据集中 除了TDBGrid构件外 当用户修改了一个字段的值 还需要把输入焦点移走 新的数据才写到数据集中 在移走输入焦点之前 用户随时可以按ESC键取消修改 在TDBGrid构件建立的栅格中 当用户修改了一个字段的值 还需要把输入焦点移到另一条记录上 新的数据才写到数据集中

禁止和允许数据刷新

当程序正在遍历整个数据集或者搜索一个特定的记录时 应当暂时禁止数据控件刷新数据 这样能加快遍历或搜索的速度 防止屏幕总是在闪烁 调用数据集的DisableControls可以暂时禁止连接这个数据集的数据控件刷新数据 DisableControls函数通常在循环 *** 作前调用 等循环结束后 程序应当立即调用数据集构件的EnableControls函数重新允许刷新数据 为了确保最后总是能恢复刷新 建议采用Try Finally结构 这样 即使在循环中出现异常 也可以保证总能调用EnableControls

下面的代码演示了怎样调用DisableControls和EnableControls函数

CustTable DisableControls;TryCustTable First;While not CustTable EOF DoBegin CustTable Next;End;FinallyCustTable EnableControls;End;

手动刷新数据

调用数据集的Refresh可以读取数据集中最新的数据并刷新数据控件 这个功能在多用户环境尤其有用 因为其他用户有可能已改变了数据集中的数据 有时候 调用Refresh可能会导致意想不到的结果 例如 如果另一个用户已经删除了一条记录 调用Refresh后 这条记录将从数据控件中消失

显示单个字段的数据控件

有的数据控件以数据库的一个或几个字段作为工作内容 如TDBText和TDBEdit 而有的数据控件以整个数据集为工作内容 如TDBGrid和TDBNavigator 显示单个字段的数据控件往往是从一个标准的Windows控件演化而来的 例如 TDBEdit构件就可以认为是TEdit的数据感知版本

把数据作为标签显示

TDBText构件是一个只读的数据控件 它非常类似于TLabel构件和TStaticText构件 TDBText构件能够把数据作为标签显示 用来标注其他控件 例如 可以用一个TDBText构件显示名称(Common_Name字段)

TDBText构件需要指定一个字段 当用户使用导航器或其他手段浏览记录时 TDBText构件显示的数据将自动变化 因为TDBText构件总是显示当前记录的数据

TDBText构件的AutoSize属性一般要设为True 这是因为字段的内容长度可能是不同的 如果AutoSize属性设为False 有些较长的内容可能会被截断

显示和编辑数据

TDBText构件只能显示数据 不能编辑数据 要既能显示数据 又能编辑数据 就要用到TDBEdit构件 TDBEdit可以认为是TEdit的数据感知(Data Aware)版本 例如 有一个TDataSource构件叫CustomersSource 它的DataSet属性指向一个TTable构件叫CustomersTable 把一个TDBEdit构件放在窗体上 其DataSource属性设为CustomersSource 把它的DataField属性设为CustNo 这个TDBEdit构件马上就能显示CustNo字段的值 用户可以在编辑框中键入新的值

显示和编辑多行文本

TDBMemo构件是TMemo构件的数据感知版本 可以显示dBASE和Paradox数据库中备注字段的内容

与TDBEdit不同的是 TDBMemo能够以多行的形式显示文本 同时也允许用户键入多行文本

默认情况下 TDBMemo允许用户修改它显示的文本 如果不想让用户修改文本 只要把ReadOnly属性设为True即可

要允许用户在文本中插入一个制表符 应当把WantTabs属性设为True 否则 当用户按下Tab键 将把输入焦点移走 而不是插入制表符 要限制用户最多可输入的字符数 可以设置MaxLength属性 如果这个属性设为 表示没有限制

此外 ScrollBars属性可以设置要不要加上滚动栏 WordWrap属性可以设置是否允许自动绕回 Alignment属性可以设置文本的对齐方式 在运行期 您可以调用CutToClipboard和CopyToClipboard函数把选择的文本剪切和复制到剪贴板中 调用PasteFromClipboard能够粘贴剪贴板中的文本

lishixinzhi/Article/program/Delphi/201311/8453

内建的Bold对象编辑界面

双击BoldGrid中左侧的箭头 或者记录可以激活对象编辑对话框 对象编辑对话框可以同时启动多个 如下图所示意

在BoldGrid中 我们可以使用ctrl+鼠标点击来多选对象 也可以点击网格左上角来选中所有的对象 但是默认的BoldGrid对象编辑器不支持人员和账目对象的关联的显示和编辑 但d出的对象编辑器则支持这些关联 上图框起来的箭头 可以用来拖放对象 将哈巴狗拖动到PayPerson的位置 就可以建立支付人同账目对象之间的关联了

还有一点要注意的是d出式对象编辑器并不是同Grid同步绑定的 因此我们可以打开多个编辑器的同时还可以在网格内的记录间导航到不同的位置 两者可以做到互不影响游标 而传统的数据库程序无法做到这点 因为当游标改变时 会同步改变所有同DataSource绑定的数据感知组件中的内容

退出系统后 可以看到Data xml中记录了刚才输入的信息

主从关系的实现

使用上面的Bold程序 再输入一个大尾巴兔兔的用户 你会发现有一个问题 就是大尾巴兔兔同志目前没有任何账目支出 但是点选到大尾巴兔兔对象上时 账目网格组件仍然是显示所有的账目信息 而没有实现主从关联

为了实现主从关系 需要修改一下账目对象的BoldListHandle组件的属性 将blhAcct的RootHandle属性由原来的DmMoney bshMoney改成blhPerson 表示父对象是人员 同时要将Expression属性改成Pay 另外为了能够在账目网格中显示同账目关联的人员信息 双击bgAcct网格 添加一个新的Column 设定它的BoldProperties Expression为PayPerson name 表示字段用来显示支付账目人的名字 见下图示意

再次运行程序 可以看到这回实现了真正的主从关联 当点击哈巴狗时 只显示同哈巴狗关联的账目 同时 如果这时点击账目网格的添加命令的话 新建的对象的PayPerson自动设定为哈巴狗 如下图示意

级联删除的实现

前面虽然我们实现了主从关系 但是将所有人员都删除后 你会发现data xml文件中仍然有账目信息 这表明 删除人员时 没有将同人员绑定的账目信息删除 也就是说并没有实现级联删除

为了更形象的察看这一现象 在界面添加一个BoldGrid BoldNavigator和BoldListHandle来显示系统中所有的对象 设定BoldListHandle的RootHandle属性为DmMoney bshMoney 设定Expression属性为MoneyModelRoot allInstances表示显示系统中所有的对象实例

然后向前面一样将BoldListHandle绑定到BoldGrid和BoldNavigator 并创建默认的Columns 再次运行后的效果如下图所示意

可以看到全部对象列表中有两个字段 type字段表示系统中对象的类型 而AsString字段则显示对象的字符串表达 但是默认Person对象的AsString字段里面显示的是对象组件加类别字符串 而AcctItem对象的AsString显示的是对象的Amount属性 但是为了观察对象被删除的情况 我希望能够显示更有意义的字符串 如显示人员的名称 显示账目的名称及支付人

因此需要修改模型中对象默认字符串的定义 双击数据模块中bmMoney 激活Bold UML Editor 选中Person对象 设定Default string rep为name 表示默认的AsString属性为人员的名称 见下图示意

同样的 设定AcctItem的Default string rep为payPerson name+ +name 表示AsString由支付人的名称及账目名称构成

再次运行程序 显示效果示意如下

这时 将哈巴狗从人员列表中删除后 界面示意图如下

可以看到账目对象大白菜和化妆品仍然还在 只是支付人信息为空了 看来账目对象确实没有被级联删除 为了实现级联删除 再次打开Bold UML Editor 展开PayAssoc关联 选中Pay 然后设定Delete action为Cascade 表示使用级联删除 见下图示意

再次运行程序 输入人员信息及人员账目信息后 再删除人员 会发现这回将绑定的账目信息也一同删除了

总结

lishixinzhi/Article/program/Delphi/201311/24783

以上就是关于用Delphi开发数据库程序经验三则全部的内容,包括:用Delphi开发数据库程序经验三则、Delphi数据库控件使用入门(一)、Delphi深度探索之使用Bold开发数据库应用(3)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9446778.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存