BDE 到 FireDAC:打包 table,重新生成索引

BDE to FireDAC: pack table, regenerate index

我们的一个旧程序使用 dBase tables 和 .MDX 索引 - 其他系统也使用这些 tables,所以我们坚持使用它们。我们希望在我们的软件中用 FireDAC 替换 BDE。 FireDAC 似乎没有提供 BDE 方法 DbiRegenIndex 和 DbiPackTable(分别重新生成索引和打包 table)——有没有办法使用 FireDAC 执行这些功能?

下面的代码显示了如何使用 MS dBase 驱动程序索引 dBase table。我有 使用 Ado 组件,而不是 FireDAC,因为它更容易设置所有 它们在代码中的属性,所以你可以看到我在做什么。请注意,以及 CREATE INDEX 驱动程序还支持 DROP INDEX。参见例如https://docs.microsoft.com/en-us/sql/odbc/microsoft/create-index-for-paradox (适用于 Paradox,但也适用于 dBase)

要为此项目进行设置,您需要设置一个名为 DBFTest 的 ODBC 系统 DSN,使用 MS dBase 驱动程序。

将此 Ado 示例转换为 FireDAC 应该很简单。

type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    btnCreateTable: TButton;
    ADOQuery1: TADOQuery;
    btnOpenTable: TButton;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    btnDropTable: TButton;
    btnAddIndex: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnAddIndexClick(Sender: TObject);
    procedure btnCreateTableClick(Sender: TObject);
    procedure btnDropTableClick(Sender: TObject);
    procedure btnOpenTableClick(Sender: TObject);
  public
    procedure CreatedBaseTable;
  end;

[...]

procedure TForm1.FormCreate(Sender: TObject);
begin
  AdoConnection1.ConnectionString :=  'Provider=MSDASQL.1;Persist Security Info=False;Data Source=DBFTest';
end;

procedure TForm1.btnAddIndexClick(Sender: TObject);
var
  Sql : String;
begin
  if AdoQuery1.Active then
    AdoQuery1.Close;

  Sql := 'create index byID on dBaseTest (ID)';
  AdoConnection1.Execute(Sql);

  AdoQuery1.Open;
end;

procedure TForm1.btnCreateTableClick(Sender: TObject);
begin
  CreatedBaseTable;
end;

procedure TForm1.btnDropTableClick(Sender: TObject);
var
  Sql : String;
begin
  Sql := 'drop table dBaseTest';
  AdoConnection1.Execute(Sql);
end;

procedure TForm1.btnOpenTableClick(Sender: TObject);
begin
  AdoQuery1.SQL.Text := 'select * from dBaseTest';
  AdoQuery1.Open;
end;

procedure TForm1.CreatedBaseTable;
var
  Sql : String;
  i : Integer;
begin
  Screen.Cursor := crSqlWait;
  Update;
  try
    Sql := 'create table dBaseTest(ID int, AName char(20))';
    AdoConnection1.Execute(Sql);
    for i := 1 to 100 do begin
       Sql := Format('insert into dBaseTest(ID, AName) values(%d, ''%s'')', [i, 'Name' + IntToStr(i)]);
      AdoConnection1.Execute(Sql);
    end;
  finally
    Screen.Cursor := crDefault
  end;
end;

显然,对于 "regenerate" 这样的索引,如果它们存在,您只需删除它们,如果它们不存在,则处理任何异常,然后重新创建它们。

我不知道 dBase 驱动程序是否支持 "pack table" 命令,但您可能可以自己使用 INSERT INTO ... SELECT * FROM ...”来复制将活动行放入临时 table,然后从工作 table 中删除所有行,然后将它们从临时行复制回来。