更改 dbf 文件的列名

Change column name of a dbf file

我的数据库文件 (.dbf) 中有这些项目

INDICE  NOME    COR ESTILO  ESCALA
100     SAOJOAO      18      0,00

我需要将 INDICE 的列名称更改为 ID,所以我使用此代码:

  while not ADOQuery1.Eof do
    begin
      Adoquery1.Edit;
      ADOQuery1.FieldByName('NOME').TEXT:= 'ID';
      Adoquery1.Post;
      ADOQuery1.Next;
    end;

当我 运行 以上时,我得到这些结果:

INDICE  NOME    COR ESTILO  ESCALA
 ID     SAOJOAO      18      0,00

使用的连接字符串: Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=C:_workspace\projects\DBFEditor\te‌​mp

我有一个系统需要导入 dbf 文件并且只能识别具有 id 列名称的文件。

下面的演示项目展示了一种完成您似乎想要的事情的方法。我不这么说 这是最有效或最好的方法,但它可能和您可能得到的一样简单。

如果您只想更改 Delphi 应用程序中字段的显示名称,例如在 DBGrid 的 header 列中,您可以通过更改 DisplayLabel 属性 相关字段 (AdoQuery1.FieldByName('INDICE').DisplayLabel := 'ID'),正如我之前在评论中所说。但是在您最近的编辑中,您实际上想要做的似乎是将读取数据文件的程序看到的 INDICE 列 的名称 更改为 ID。为此,您必须更改 .DBF 文件的 on-disk 结构。这就是我下面的代码所做的。

它使用为 MS ODBC driver 为 dBase 文件设置的用户 DSN 作为 AdoConnection 连接字符串的目标。

理想情况下,我希望找到 ALTER TABLE Sql 语句的风格 这将简单地重命名 INDICE 列,但 MS dBase driver 似乎没有 支持它,因为它在我尝试时生成了一个异常。因此,我的代码通过复制 table 及其内容来工作,并将 INDICE 列重命名为 ID.

简而言之,程序

  1. 创建一个 table MATest,其中第一列名为 INDICE 和其他几个列,并向其中插入一行。这只是为了设置一个table来工作。

  2. 创建第二个 table MATest2,其结构与 MATest 相同,除了第一个 列被命名为 ID 而不是 INDICE。

  3. 通过使用 INSERT INTO Sql 语句从 MATest 复制所有行来填充 MATest2 table。

你想做的重要步骤都在btnCreateTableCopyClick 程序。请注意,您必须注释掉前两行,这会删除 table MATest2 第一次 运行 应用程序,否则它会隐晦地抱怨, 不能删除 MATest2,因为它不存在。

我将根据您的数据对代码进行必要的调整。

代码:

type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    btnCreateSrcTable: TButton;
    ADOQuery1: TADOQuery;
    btnOpenSrcTable: TButton;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    btnDropTable: TButton;
    btnCreateTableCopy: TButton;
    procedure btnCreateSrcTableClick(Sender: TObject);
    procedure btnDropTableClick(Sender: TObject);
    procedure btnOpenSrcTableClick(Sender: TObject);
    procedure btnCreateTableCopyClick(Sender: TObject);
  private
  protected
  public
    procedure CreateSourceTable;
  end;

[...]

procedure TForm1.btnCreateTableCopyClick(Sender: TObject);
var
  Sql : String;
begin
  Sql := 'drop table MATest2';
  AdoConnection1.Execute(Sql);

  Sql := 'create table MATest2(ID int, AName char(20), AValue char(20))';
  AdoConnection1.Execute(Sql);

  Sql := 'insert into MATest2 select INDICE, AName, AValue from MATest';
  AdoConnection1.Execute(Sql);
end;

procedure TForm1.btnCreateSrcTableClick(Sender: TObject);
begin
  CreateSourceTable;
end;

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

procedure TForm1.btnOpenSrcTableClick(Sender: TObject);
begin
  AdoQuery1.Open;
end;

procedure TForm1.btnCreateTableCopyClick(Sender: TObject);
var
  Sql : String;
begin
  Sql := 'drop table MATest2';
  AdoConnection1.Execute(Sql);

  Sql := 'create table MATest2(ID int, AName char(20), AValue char(20))';
  AdoConnection1.Execute(Sql);

  Sql := 'insert into MATest2 select INDICE, AName, AValue from MATest';
  AdoConnection1.Execute(Sql);
end;

procedure TForm1.CreateSourceTable;
var
  Sql : String;
begin
  Sql := 'create table MATest(INDICE int, AName char(20), AValue char(20))';
  AdoConnection1.Execute(Sql);
  Sql := 'insert into MATest(INDICE, AName, AValue) values(1, ''aaa'', ''vvv'')';
  AdoConnection1.Execute(Sql);
end;

显然,最好首先使用 ID 字段名生成数据并避免所有这些,但大概有充分的理由不能这样做。