第一章 ADO简介
1、原生ADO
OLE-DB定义了统一的COM接口作为存取各类异质数据源(关系数据库、Excel或其他文件)的标准,并且封装在COM对象之中。ADO对OLE-DB再次封装(因为OLE-DB太底层化)。
ADO架构为服务者、消费者模式。
2、Delphi中的ADO Express模型
第二章 ADOExpress介绍(一)
示例数据库为StudentCourse,有Student、Course、SC三个表。
1、基本组件介绍
(1)TADOConnection组件:
封装了原生ADO的Connection对象。提供了Pooling和Session管理功能。重要属性:ConnectionOptions(决定了异步还是同步方式连接)、IsolationLevel(代表ADO事务管理器所使用的事务IsolationLevel级别)、Mode(建立连接所允许的存取行为)。
(2)TADOCommand组件:
用来执行SQL中的数据定义语言(DDL),执行不回传结果集的SQL命令,占用资源较少。结果返回可以得用另外的DataSet接收。
(3)TADODataSet组件:
封装了ADO的RecordSet对象。重要的属性有CursorLocation、CursorType、LockType。而TADOStoredProc就是封装设定commandType为cmdStoredProc的RecordSet,TADOTable就是封装设定commandType为cmdTable的RecordSet。
TDataSet中的Open即设Active为True,Close即设Active为False。
通过分析SQLProfiler,当Open时:
1、SET FMTONLY ON select SC.Sno,Student.Sname,SC.Cno,Course.Cname,SC.score from Student,Course,SC where SC.Sno=Student.Sno and SC.Cno=Course.Cno SET FMTONLY OFF(先查询出列信息,不返回数据,只作一次)
2、select SC.Sno,Student.Sname,SC.Cno,Course.Cname,SC.score from Student,Course,SC where SC.Sno=Student.Sno and SC.Cno=Course.Cno(然后再返回数据信息)
2、MasterDetail型的设置(参见知识累积下面的MasterDetail项目)
通过从表的DataSource属性连接主表,从表的SQL含有参数,参数即主表的外码。
3、使用事务
代码模板:
Handle ADODataSet的BeforePost、AfterPost、PostError事件(这样每次Post的时候都会开启事务,当LockType为ltOptimistic时,只要游标改变就Post)。
procedure TForm1.ADODataSet1BeforePost(DataSet: TDataSet);
begin
self.ADOConnection1.BeginTrans;
end;
procedure TForm1.ADODataSet1AfterPost(DataSet: TDataSet);
begin
self.ADOConnection1.CommitTrans;
end;
procedure TForm1.ADODataSet1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
begin
self.ADOConnection1.RollbackTrans;
Action:=daAbort;
end;
在SQL Server中首先set implicit_transactions on(如果前面已经开启,就不用执行)、然后执行语句:
exec sp_executesql N'UPDATE "StudentCourse".."SC" SET "score"=@P1 WHERE "score"=@P2 AND "SCNo"=@P3', N'@P1 int,@P2 int,@P3 varchar(10)', 12, 89, '2 '
如果执行成功:IF @@TRANCOUNT > 0 COMMIT TRAN;
执行不成功:IF @@TRANCOUNT > 0 ROLLBACK TRAN
当查询的时候自动结束:set implicit_transactions off
4、BatchUpdate模式
将所有数据修改暂存于客户端缓存中,最后一次更新。
当locktype为ltBatchOptimistic时必须显示调用UpdateBatch(就算调Post都不行)即使Refresh也不会更新数据库。
UpdateBatch对多表连接也能自动更新,由于它是将更新分解,所以被更新的表必须有主码。更新的时候是按字段的顺序进行更新。
比如先更新Name字段的改变,然后再更新Score。
由于没有自动使用事务,所以前面的更改可能导致意料之外的错误。
分析自动生成的Update命令:
exec sp_executesql N'UPDATE "StudentCourse".."SC" SET "score"=@P1 WHERE "score"=@P2 AND "SCNo"=@P3', N'@P1 int,@P2 int,@P3 varchar(10)', 70, 65, '3 '
可见其不仅使用了主键作where同时还用了原字段的原有值。所以当将数据读到内存后,如果同时对数据源进行更改,再UpdateBatch时就会异常。
如果想取消更改,就用CancelBatch,注意:它是将缓冲中的旧值替换更改后的值,并不读数据库。
UpdateBatch也可以对视图进行更新。
在BatchUpdate下设置FilterGroup可以根据用户需要过滤数据(涉及各种修改、删除、添加的情况)。当然,必须先设置Filter为True再设置条件。
使用BatchUpdate就可以使用BriefCase编程模型,类似ADO.NET,将数据读出后SaveToFile存入文件中(有pfADTG、pfXML两种格式,当然存成XML了),断开连接。进行修改时先LoadFromFile读出,修改完后再打开连接,同时UpdateBatch。
注意:断开连接前要先置self.ADODataSet1.Connection:=nil;,否则关闭Connection的时候自动把ADODataSet的Active置False了,这样就不能编辑数据集了。
XML文件中先存储架构,然后存储每条记录,包括旧值新值。
5、搜寻数据
用ADODataSet的Locate或Lookup可以搜寻数据。
6、过滤数据
将Filtered设置为true就可以过滤,当然要设置过滤条件。
Filter:=条件
当过滤很复杂的条件的时候,就需要用编写过滤函数。
ADODataSet1.OnFilterRecord:=FilterRoutine;
FilterRoutine里通过设置Accept参数的True或False来决定该记录是否被过滤,OnFilterRecord是在检索每条记录的时候触发。
7、排序数据
ADO数据集的Sort属性可以实现排序