更改dbf文件的列名称

时间:2016-10-19 15:48:27

标签: delphi ado delphi-xe dbase

我的dbase文件(.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列名的文件。

1 个答案:

答案 0 :(得分:3)

下面的演示项目展示了一种做你想要的方法。我没有声称 这是最有效的方式或最好的方式,但它可能就像你可能得到的一样简单。

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

它使用为MSase ODBC驱动程序设置的用户DSN for dBase文件作为AdoConnection连接字符串的目标。

理想情况下,我希望找到ALTER TABLE Sql语句的味道 它只是重命名INDICE列,但似乎没有MS dBase驱动程序 支持它,因为它在我尝试时产生了异常。因此,我的代码通过制作表及其内容的副本来工作,并将INDICE列重命名为ID。

简而言之,程序

  1. 使用名为INDICE的第一列和其他几列创建一个表MATest,并在其中插入一行。这只是为了设置一个工作表。

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

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

  4. 您想要做的重要步骤是在btnCreateTableCopyClick中执行的 程序。请注意,您必须注释掉前两行,这会删除 在第一次运行应用程序时使用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字段名生成数据会更好,并避免所有这些,但可能有一个很好的理由,为什么你不能。

相关问题