2

Delphiはマルチフィールドインデックスを好まないようです。

希望の順序で行が含まれるテーブルになるように、テーブルを物理的に並べ替えるにはどうすればよいですか?

例:

mytable.dbf

Field   Field-Name   Field-Type   Size
  0     Payer        Character     35
  1     Payee        Character     35
  2     PayDate      Date
  3     Amount       Currency

「Payee」+「Payer」のアルファベット順に並べ替えた表を作成する必要があります

「Payee+Payer」のインデックスを使用しようとすると、エラーが発生しました。

「フィールドインデックスが範囲外です」

4

5 に答える 5

4

インデックスフィールド名は、プラス記号ではなくセミコロンで区切る必要があります。それを試してみてください、それはうまくいくはずです。

于 2010-02-23T14:36:13.807 に答える
3

さて、注文してみましょう。

まず、テーブルを物理的に並べ替えることはお勧めできません。実際、ほとんどのRDBMSはこの機能を提供していません。通常、全表スキャン(自然スキャンと呼ばれることもあります)を強制しないために、テーブルがソート/検索されると彼が考えるテーブルフィールドにインデックスを作成します。

ご覧のとおり、テーブルを並べ替えるための最初のステップは通常、インデックスの作成です。これはのステップであり、通常は「設計時」に1回実行されます。この後、DBエンジンはインデックスを自動的に更新するように注意します。

インデックスの作成は、(通常は)Delphi(またはその他の開発ツール)ではなく、RDBMSの管理ツール(テーブルの作成時に使用したものと同じツール)を使用して、ユーザー(開発者)が行います。

「DBエンジン」が実際にDelphiメモリデータセット(TClientDataSet)である場合は、IndexDefsプロパティに移動して開き、新しいインデックスを追加して、それに応じてプロパティを設定します。私たちの議論で興味深い特性はですFields。に設定しPayee;Payerます。もNameegに設定します。「idxPayee」。他のTDataSetの子孫を使用する場合は、DBエンジンのドキュメントを参照するか、SO.comで詳細を提供する別の質問をしてください。

次に、インデックスを使用します。(IOW、あなたが言うように、テーブルをソートするために)。プログラムで(設計時または実行時のいずれかで)、「テーブル」でIndexName「idxPayee」または指定または設定したその他の有効な名前に設定IndexFieldNamesPayee;Payerます。

上記はTClientDataSetに基づく例であることにもう一度注意してください。上記から保持する必要があるのは(使用しない場合)、使用するにはインデックスがすでに作成されている必要があるということです。

また、あなたの質問に答えるために、はい、いくつかの「テーブル」タイプ(Delphiの用語ではTDataSetの子孫)があり、Sortメソッド(または同様のもの)またはSortFieldsプロパティのいずれかを介してソートをサポートします。

しかし、最近では通常、SQLバックエンドを使用する場合、対応する管理ツールを使用してインデックスを作成し、(Delphiを使用して)を発行することをお勧めしSELECT * FROM myTable ORDER BY Field1ます。

HTH

于 2010-02-23T17:08:28.193 に答える
1

まだBDEを使用している場合は、BDEAPIを使用してDBFテーブルを物理的に並べ替えることができます。

uses
  DbiProcs, DbiTypes, DBIErrs;

procedure SortTable(Table: TTable; const FieldNums: array of Word; CaseInsensitive: Boolean = False; Descending: Boolean = False);
var
  DBHandle: hDBIDb;
  RecordCount: Integer;
  Order: SORTOrder;
begin
  if Length(FieldNums) = 0 then
    Exit;

  Table.Open;
  RecordCount := Table.RecordCount;
  if RecordCount = 0 then
    Exit;
  DBHandle := Table.DBHandle;
  Table.Close;

  if Descending then
    Order := sortDESCEND
  else
    Order := sortASCEND;

  Check(DbiSortTable(DBHandle, PAnsiChar(Table.TableName), nil, nil, nil, nil, nil,
    Length(FieldNums), @FieldNums[0], @CaseInsensitive, @Order, nil, False, nil, RecordCount));
end;

たとえば、あなたの場合:

  SortTable(Table1, [2, 1]); // sort by Payee, Payer
于 2010-02-25T08:49:39.663 に答える
0

確認できませんが、IndexFieldNames = "Payee、Payer"を試してください。
これらの2つのフィールドによるインデックスが存在することを確認してください。

于 2010-02-23T14:34:15.497 に答える
0

1回の呼び出しでTTable.AddIndexメソッドを使用して、テーブルにインデックスを作成できます。これにより、データを読み取るときにデータが並べ替えられます。つまり、TTable.IndexNameプロパティを新しいインデックスに設定して新しいインデックスを使用する場合です。次に例を示します。

xTable.AddIndex('NewIndex','Field1;Field2',[ixCaseInsensitive]);
xTable.IndexName := 'NewIndex';
// Read the table from top to bottom
xTable.First;
while not xTable.EOF do begin
  ..
  xTable.Next;
end;
于 2010-02-28T08:17:13.850 に答える