手册中关于怎样使用TQuery的误导,Delphi数据库编
分类:关于计算机

Q:手册中关于怎样使用TQuery 的误导

深入数据集里的数据
数据的状态
  用Delphi和ADO开发数据库应用程序时,大部分工作需要数据集(dataset )组件的协助。为了创建一个基于ADO的程序,Delphi提供了一些数据集组件:TAdoTable、TAdoQuery等等用于检索、显示和修改数据库内的表或查询到的数据。

A:用Delphi开发数据库时经常会用到TQuery, 手册中有很多关于它的例子, 大致结构如下:

     在本教程的第五章,我们将了解怎样来显示、浏览和读取数据——通过数据集组件一些有趣的属性、事件和方法来实现。

Query1.Close;
Query1.ParamByName(ID).AsString := 001;
Query1.Open;
String := Query1.FieldByName(ID).AsString;

      挑选、设置、连接和获得(Pick, set, connect and get)

很多用户根据这段例子开发时会遇到速度慢, 资源耗用多, 甚至引发资源不足的异常。 这是为什么呢, 其实是手册的例子有些片面, 误导了大家。

      鉴于这是第五章,你应该熟悉了创建一个数据浏览窗体所需要的步骤。在第四章,我们一步步建立了个简单的数据浏览窗体。本章将继续用它来讨论。

Delphi有一个重要的特性是DB aware, 把DBGrid与Query连接在一起, Query的结果集就会自动的显示在DBGrid中。 为了保证DBGrid总显示查询结果, 需要Query总保持Active。 当修改Query的查询条件时, 先关闭Query, 修改完查询条件以后再打开它。 这就是上面代码的含义。

     目前为止,我们仅用过一个(ADO)数据集组件——TAdoTable。下面,有必要了解一下TADOQuery和TADODataSet(数据集组件)共同的方法和事件。

问题是,当Query不和DB aware组件连接时, 比如在计算字段的事件中取其它表的内容, 应该怎样写代码。 这时候不需要让Query保持Active, 相反, 为了减少不必要的浪费, 应该是保持DeActive。 所以代码应该如下:

      芝麻开门;芝麻关门(Open Sesame ; Close Sesame)

Query1.ParamByName(ID).AsString := 001;
Query1.Open;
String := Query1.FieldByName(ID).AsString;
Query1.Close;

      Delphi数据库开发的出色功能之一就是:可以在程序设计时对数据进行处理。你可以回忆一下——在上一章,我们使用Active属性便在设计时建立了数据的活动连接。

您在使用Query的时候要注意根据实际情况选择适当的方法, 不要被手册误导。

     不难理解,在开始处理表的数据之前,程序必须先打开数据集。Delphi有两种方法实现此功能。一是在设计或运行时将Active属性设置为True;二是运行时调用Open方法。例如,添加以下代码到窗体的OnCreate事件句柄中,获得来自ADOTable1组件的数据:

 

      ADOTable1.Open;

的误导 A:用Delphi开发数据库时经常会用到TQuery, 手册中有很多关于它的例子, 大致结构如下: Query1.Close;...

      注:每个ADO数据集都可通过它自身的ConnectionString属性,或一个ADOConnection组件(及其ConnectionString)访问数据库中的数据。如果ADOTable1组件与ADOConnection1组件相连(推荐使用此方式),打开ADOTable将激活相应的ADOConnection组件。ADOConnection提供两个将被执行的事件:OnWillConnect和OnConnectComplete。

      Open方法设置Active属性为True并激活连接。当用完连接后,我们可以设置Active属性为False或调用Close方法断开连接。通常放在窗体的OnClose事件句柄中:

      ADOTable1.Close;

      在继续之前,需知道对数据集方法和属性的处理,依赖于对数据当前状态的了解。简而言之,数据集的State(状态)属性决定任何时候数据集上的什么行为可以发生或不发生。

如何做(How are you doing?)

      如果数据集是关闭的,数据的State将显示为Inactive(非活动)连接。连接关闭时,任何操作、行为或方法都无法作用于数据。首次打开连接时,数据集处于默认的Browse(浏览)状态。你应该始终了解“你的”数据所在的状态。例如,当我们把数据集连接到DBGrid时,用户能够看到底层的数据集(或记录),但要改变某些数据时,必须把State设置为Edit。
      认识到程序处理数据时,数据集状态都在不停改变是非常重要的。例如,当浏览DBGrid中数据时(为Browse状态),用户编辑记录时,自动改变状态为Edit。当然,在数据感知控件(DBGrid、DBEdit)AutoEdit属性设为True时,这是默认行为。

     但是,但是,我们该如何获得状态呢? ADOTable(或任何其他数据集组件)没有处理状态改变的触发器。

     好,让我们看一看:对每个数据集组件,我们通常用一个数据源组件来呈现于一个或多个数据感知控件的连接。就是这样。

     每个数据源组件都有一个OnStateChange事件,在底层数据集改变时触发。把下面的代码放到OnStateChange事件句柄中,用窗体的标题来显示ADOTable1数据集组件的当前状态:

 

[delphi]
procedure TForm1.DataSource1StateChange 
  (Sender: TObject); 
var ds: string; 
begin 
 case ADOTable1.State of 
  dsInactive :  ds := 'Closed'; 
  dsBrowse :  ds := 'Browsing'; 
  dsEdit    :  ds := 'Editing'; 
  dsInsert  :  ds := 'New record inserting'; 
 else 
  ds := 'Other states' 
 end; 
 Caption := 'ADOTable1 state: ' + ds; 
end; 

procedure TForm1.DataSource1StateChange
  (Sender: TObject);
var ds: string;
begin
 case ADOTable1.State of
  dsInactive :  ds := 'Closed';
  dsBrowse :  ds := 'Browsing';
  dsEdit    :  ds := 'Editing';
  dsInsert  :  ds := 'New record inserting';
 else
  ds := 'Other states'
 end;
 Caption := 'ADOTable1 state: ' + ds;
end;

From BOF to EOF and back in the Middle
  在上一章,我们用DBNavigator组件来浏览数据集。作为一个可视化的数据集浏览控件,用户可在运行时单击其按钮,来遍历数据集里的记录。

Movingon from BOF to EOF

  遍历记录集以及概括某些值时,我们需要用到数据集组件中的方法。看看以下代码:

[delphi] 
... 
 ADOTable1.DisableControls; 
 try 
  ADOTable1.First;                         //将当前行指向到数据集的第一条记录  
  while not ADOTable1.EOF do   //EOF(BOF)属性指出这是否是数据集的最后(第一行)记录。  
begin; 
    Do_Summing_Calculation;   //求和等表达式语句  
    ADOTable1.Next;                    //将当前行移动至数据集的下一条记录  
  end; 
 finally 
  ADOTable1.EnableControls; 
 end; 
... 

...
 ADOTable1.DisableControls;
 try
  ADOTable1.First;                         //将当前行指向到数据集的第一条记录
  while not ADOTable1.EOF do   //EOF(BOF)属性指出这是否是数据集的最后(第一行)记录。
begin;
    Do_Summing_Calculation;   //求和等表达式语句
    ADOTable1.Next;                    //将当前行移动至数据集的下一条记录
  end;
 finally
  ADOTable1.EnableControls;
 end;
...
多数情况下,数据集连接到一个或多个数据感知控件。长遍历时,发生数据感知控件从数据集“断开”,会是相当有趣的——为防止数据感知控件随活动记录的每次变化而更新。用DisableControls和EnableControls禁用和启用与数据集关联控件的数据显示。

异常捕捉(try-finally)程序块——确保异常发生时,所有的数据感知控件依然连接到数据集。

Bookmarking

  调用上述代码前,*指针*很可能在数据集某些*中间*位置——比如用户正在用DBGrid浏览一个数据集。代码使*指针*从*中间*当前行移到结束(EOF)行,导致程序失去原来的位置。如果我们可以存储当前位置并在遍历完成后回到此位置(再次),这会让用户感到非常友好。当然,Delphi具有此功能。 ADOTable(及其他继承至TDataSet的控件)拥有Bookmark属性用来存储和设置当前记录的位置。用法如下:

[delphi]
var Bok : TBookmarkStr 
... 
Bok :=ADOTable1.Bookmark; 
{iterationcode} 
ADOTable1.Bookmark:= Bok; 

var Bok : TBookmarkStr
...
Bok :=ADOTable1.Bookmark;
{iterationcode}
ADOTable1.Bookmark:= Bok;

 

Thevalue of data
  前面代码中的Do_Summing_Calculation部分,多用来获取数据集中某些字段(列)的值,并进行求和等操作。

当我们在谈论数据集中的记录值时,也就是在谈论数据字段的值。正如前面章节中看到的,用来表示数据集字段的不可见字段组件——在示例中,我们用Object Inspector来设置一个数据集的持久性字段列表。

数据感知控件连接到一个数据集后,用户通过示例中的那些操作来遍历数据集。当我们想直接在代码中使用这些值时,我们需要知道如何读取它们。

默认情况下,Delphi用以下方式命名字段对象:表名+字段名。也就是说,如果连接到的表中有Type字段,那么该字段对象的名称是:ADOTable1Type。

要访问字段的数据值,可用以下方式。

[delphi] 
ADOTable1Type.Value 
ADOTable1.Fields[x].Value 
ADOTable1.FieldByName('Type').Value 

ADOTable1Type.Value
ADOTable1.Fields[x].Value
ADOTable1.FieldByName('Type').Value注:数据集的所有字段都存放在字段数组中。 x表示字段在字段数组中的位置。

Value属性持有该字段对象的数据值。由于值是varian 类型的,因此需要强制转换为我们目前需要的类型。换言之,应用程序应使用AsString属性将字段中的值(日期、整数、货币...)转换为一个字符串——当我们需要字符串形式的字段值时。

现在,我们可以写出整个代码了,用来遍历记录集并计算表中有多少个“database”应用。(当然,是用的我们AboutDelphi.mdb数据库中的Applications表)。

[delphi]
var 
  Bok : TBookmarkStr; 
  ict : Integer; 
begin 
  ict:=0; 
  Bok:=ADOTable1.Bookmark; 
  try 
    ADOTable1.DisableControls; 
    try 
      ADOTable1.First; 
      while not ADOTable1.EOF do 
      begin 
        if ADOTable1.FieldByName('Type').AsString = 'database' then Inc(ict); 
        //if ADOTable1Type.AsString = 'database' then Inc(ict);    //其他两种方式  
        //if ADOTable1.Fields[3].AsString = 'database' then Inc(ict);  //双击ADOTable1查看,从上之下从0开始计数  
        ADOTable1.Next; 
      end; 
    finally 
      ADOTable1.EnableControls; 
    end; 
  finally 
    ADOTable1.Bookmark:=Bok; 
  end; 
  ShowMessage('Number of database apps: ' + IntToStr(ict)); 

var
  Bok : TBookmarkStr;
  ict : Integer;
begin
  ict:=0;
  Bok:=ADOTable1.Bookmark;
  try
    ADOTable1.DisableControls;
    try
      ADOTable1.First;
      while not ADOTable1.EOF do
      begin
        if ADOTable1.FieldByName('Type').AsString = 'database' then Inc(ict);
        //if ADOTable1Type.AsString = 'database' then Inc(ict);    //其他两种方式
        //if ADOTable1.Fields[3].AsString = 'database' then Inc(ict);  //双击ADOTable1查看,从上之下从0开始计数
        ADOTable1.Next;
      end;
    finally
      ADOTable1.EnableControls;
    end;
  finally
    ADOTable1.Bookmark:=Bok;
  end;
  ShowMessage('Number of database apps: ' + IntToStr(ict));我同意!我们应为上述目的而使用ADOQuery!

这就是第五章内容。下次,我们将看到如何添加,删除和插入记录集到数据库表中。

 

数据的状态 用Delphi和ADO开发数据库应用程序时,大部分工作需要数据集(dataset )组件的协助。为了创建一个基于AD...

本文由正版必中一肖图发布于关于计算机,转载请注明出处:手册中关于怎样使用TQuery的误导,Delphi数据库编

上一篇:两台Linux主机之间scp复制文件 下一篇:没有了
猜你喜欢
热门排行
精彩图文