0

コードの冗長性のため、通常の ADOQuery 処理を独自のメソッドに一般化し、そのメソッドはクエリの _RecordSet を返します。今、そのメソッド内のクエリ結果をチェックすると、問題なくチェックアウトされます。しかし、返された _RecordSet は空または nil のようです (例外: EOleException 'アイテムが対応する名前または序数のコレクションに見つかりません。' ) 収集したものから、クエリの _RecordSet のクローンを返す必要があるようです。これまで私は使ってみました

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

TADOQuery.RecordSet._xClone()方法

失敗しただけでなく、これらの方法も機能しませんでした(いくつかのコンポーネントが認識されず、バージョンの違いが推測されます)。

クエリに使用するコード:

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;

誰かが以前にこの問題を解決し、適切な答えを知っているか、役立つコンテンツに私を導くことができますか?

4

2 に答える 2

1

あなたのクレイジーなふざけた態度のどれがよりクレイジーなのかわかりません:

  1. 関数内でデータベースをセットアップして接続し、この関数内でクエリを実行し、クエリのたびにデータベースに接続すると、非常に遅くなります。

  2. ADO Query オブジェクトは、関数の内部よりも長い有効期間を持つ必要があります。これはコードのにおい、深刻なものです。

  3. レコードセットが属しているクエリ内に保持します。

  4. 通常の人は TDataModule を作成し、アプリケーションの存続期間中はオブジェクトを残しておき、次のコードを使用して再クエリします。

    クエリ。アクティブ:= false; クエリ。アクティブ:= true;

データベースに接続する必要がなく、データが必要になるたびに接続とクエリを作成および破棄する必要がない場合、アプリの速度が向上することを確認してください。

戻ってきた _recordsets でいったい何をしているのですか? C# で ADO を学びましたか? Delphi で C# ADO.net のイディオムを使用しようとしていますか? しないでください。あんな事はしないで。

于 2012-07-07T13:23:48.153 に答える
0

返された RecordSet は、finally ステートメントで閉じているため、nil/empty です。これが、戻る前に RecordSet のクローンを作成しようとした理由だと思いますか? クローンを作成すると、同じ RecordSet への別のポインターが作成されるため、RecordSet を閉じると、クローンも nil/empty を返します。

ベンが示唆したように、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

それが役立つことを願っています

于 2012-07-09T15:20:52.617 に答える