Delphi2005 - 在另一种方法中使用TADOQuery结果

时间:2012-07-07 12:34:26

标签: delphi clone recordset tadoquery

由于代码冗余,我将通常的ADOQuery处理概括为它自己的方法,该方法返回查询的_RecordSet。 现在,当我在该方法中检查查询结果时,它们会检查出来。但是返回的_RecordSet似乎是空的或者为零(例外: EOleException'项目在集合中找不到相应的名称或序号。') 从我收集的内容来看,我似乎需要返回查询的_RecordSet的克隆。到目前为止,我已尝试使用

res := qr.Recordset.Clone(adLockUnspecified); Result := res;

TADOQuery.RecordSet._xClone()方法

失败,以及THESE方法,没有一个工作(几个组件无法识别,我猜的版本差异)。

我用于查询的代码:

function queryDb(const s: WideString; const dc: boolean = true): _RecordSet;
var
  ds: String;
  conn: TADOConnection;
  qr: TADOQuery;
  res: _RecordSet;
begin
  Result := nil;
  conn := TADOConnection.Create(nil);
  qr := TADOQuery.Create(nil);
  try
    ds := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
          + ExtractFilePath(Application.ExeName)
          + 'gdkp.mdb;Persist Security Info=False';
    conn.ConnectionString := ds;
    conn.LoginPrompt := false;
    conn.Connected := true;
    qr.Connection := conn;
    if(dc = true)then begin
      qr.DisableControls
    end;
    qr.SQL.Add(s);
    qr.Open;
    Result := qr.Recordset;
  finally
    conn.Free;
    qr.Free;
  end;
end;

有人之前是否已经克服了这个问题并且知道合适的答案,或者可以指导我找到有用的内容?

2 个答案:

答案 0 :(得分:1)

我不知道哪些疯狂的滑稽动作更疯狂:

  1. 设置并连接到函数内部的数据库并在此函数中进行查询,连接到数据库每次查询,将会非常慢。

  2. ADO Query对象的生命周期应比函数内部长。这是一种代码味道,是一种严重的气味。

  3. 将记录集保留在查询所在的位置。

  4. 普通人创建TDataModules并在其应用的生命周期内保留其对象,并使用此代码重新查询:

    query.Active:= false;  query.Active:= true;

  5. 每当您需要某些数据时,无需连接数据库,创建和拆除连接和查询,即可快速观看您的应用。

    你在回忆的那些_recordsets上做了什么?您是否在C#中学习了ADO并且尝试在Delphi中使用C#ADO.net习语?别。停止这样做。

答案 1 :(得分:0)

您返回的RecordSet为nil / empty,因为您在finally语句中将其关闭。我猜这就是为什么你在返回之前尝试克隆RecordSet的原因?克隆它会创建另一个指向同一RecordSet的指针,因此关闭RecordSet也会导致克隆返回nil / empty。

正如Ben建议的那样,有更好的方法可以像使用TDataModules一样,但这是我的方式:

我倾向于为每个数据检索或更新/插入操作编写一个函数。每个函数都作为参数传递一个ADO连接,然后运行查询/存储过程的问题包含在函数中,任何数据都作为var参数或返回值返回。我保留一个ADO连接,根据需要传递给每个函数。

例如(伪代码,因为我暂时没有完成Delphi)

function GetAllUsers(adoConnection : TAdoConnection) : TStringList    
begin
  result.clear;
  if (adoConnection <> nil) then
  begin
     ..
     ..
     // have already set up an ADOStoredProc called storedProc in this
     // part of the code block
     ..
    adoRec := storedProc.Execute();
    while not (adoRec.eof) do              // loop through record set and get our data
    begin
      result.Add(adoGetFieldStr(adoRec,'USERNAME'));    
      adoRec.MoveNext;
    end;
    adoRec.Free;
  end;
end

希望有所帮助