DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: teacherlau
今日帖子: 63
在线用户: 29
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 huo_v_wu (勇敢的螳螂) ★☆☆☆☆ -
盒子活跃会员
2022/6/23 10:37:48
标题:
D7中关于DBF创建表的字段不能超过40个的问题 浏览:826
加入我的收藏
楼主: D7 我现在需要用程序生成一个dbf的表,但这个表有120个字段,我发现只要到了40个字段,就会报错delphi record size is too big for table table dose not exist
请问下这个问题该如何解决?
function DataExports(NZYH: string; NDataset: tadodataset): Boolean; 
var

  NConStr: string;
  NPath: string;
  NStr: string;
  BaseName: string;
  TableName: string;
  table: Ttable;
begin
  try
    table := TTable.Create(nil);
    table.Close;
    table.Active := false;
    table.Exclusive := true;
    table.TableName := NZYH;
    table.TableType := ttFOXPRO;
    with table.FieldDefs do
    begin
      Clear;
      with AddFieldDef do
      begin
        Name := 'USERID_';
        DataType := ftString;
        Size := 60;
      end;

      with AddFieldDef do
      begin
        Name := 'USERNAME';
        DataType := ftString;
        Size := 60;
      end;
----------------------------------------------
-敢于学习,谦虚学习,鼓励批评!!
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/6/23 10:48:03
1楼: 1. 现在这个年代,一定要用 DBF 吗?

2. 如果用数据库工具来手动创建表,能超过40个不?

3. 是否是因为字段的名字,或者数据类型之类的问题导致,而不是 40 个导致?你能确定一定是 40 个导致?有没有试过换其它的字段名和数据类型来试试?
----------------------------------------------
-
作者:
男 huo_v_wu (勇敢的螳螂) ★☆☆☆☆ -
盒子活跃会员
2022/6/23 10:50:20
2楼: 我试验过 只要创建的字段不超过40个 就可以
----------------------------------------------
-敢于学习,谦虚学习,鼓励批评!!
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2022/6/23 11:53:03
3楼: 完全没接触过……

不过比如Oracle任何对象名称不能超过30个字符。
是不是类似的限制?

单表120个字段,可能需要考虑设计。。。
当然更多的也见过:)

面试时:三大范式,ACID四特性,特征,设计原则,可以娓娓道来。
设计时:单表几百个字段……
----------------------------------------------
Bye bye DDRFAN...
作者:
男 delphiqiw (delphi我不会) ▲▲▲△△ -
普通会员
2022/6/25 9:36:14
4楼: 还跟你字段长度有关,你可以查下dbf的限制,可以换个数据库这个太老了
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/6/25 13:36:04
5楼: type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Database1: TDatabase;
    DataSource1: TDataSource;
    Table1: TTable;
    DBGrid1: TDBGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure MyOpenDatabase;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  MyTableName          : string;          // max 31 chars
  MyFieldSize          : byte;          // max 254 chars
  MyTotalCharsPerRecord: smallint = 4000; // max 4.000 bytes DBase IV (DBase for Windows = 32.767)
  MyMaxFieldPerTable   : byte     = 255;  // max 255 DBase IV (DBase for Windows = 1.024)
  // MyFieldName          : string;          // max 31 chars
  // MyMaxIndexTagsPerMDX         : byte     = 47;         // max 47 DBase IV
  // MyMaxIndexMDXMasterOpened    : byte     = 10;         // max 10
  // MyMaxKeyExpressionSizeInChars: byte = 220;          // max 220
  // MyMaxBytesInTableDBF         : integer  = 2000000000; // max 2 billion
  // MyMaxRecordsOnTable          : integer  = 1000000000; // max 1 billion
  //
  MyTTable    : TTable;
  MyTFieldDefs: TFieldDefs;
  //
  MyFieldsNames     : TArray<string>;
  MyFieldsStringSize: byte;

function MyRecordsSizeTotal(AFieldDefs: TFieldDefs): integer;
begin
  result := -1;
  //
  if (AFieldDefs = nil) then
    exit;
  //
  try
    for var i: integer := 0 to (AFieldDefs.Count - 1) do
      result          := result + AFieldDefs.Items[i].Size;
  except
    on E: Exception do
      ShowMessage('My error:' + sLineBreak + E.Message);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyOpenDatabase;
end;

procedure TForm1.MyOpenDatabase;
begin
  Database1.Close;
  Table1.Close;
  //
  Database1.DatabaseName := ExtractFilePath(Application.ExeName); // my folder "EXE"
  Table1.DatabaseName    := Database1.DatabaseName;
  DataSource1.DataSet    := Table1;
  DBGrid1.DataSource     := DataSource1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyTotalChars: integer;
begin
  MyTTable          := nil;
  MyTFieldDefs       := nil;
  MyTableName        := 'MyDBF_0001_12345678901234567890' + '.DBF'; // DBF file...
  MyFieldsStringSize := 15;          // for test... (255 * 15) = 3.825 bytes < 4.000
  //
  if not(MyMaxFieldPerTable in [1 .. 255]) then // 1 until 255 fields
    exit;
  //
  Table1.Close; // close current table is opened!
  //
  MyTTable := TTable.Create(nil);
  try
    MyTTable.Name      := 'MyTTableName0001';
    MyTTable.TableName := MyTableName;
    MyTTable.TableType := TTableType.ttDBase; // DBF file...
    //
    MyTFieldDefs := TFieldDefs.Create(MyTTable);
    try
      for var i: integer := 0 to (MyMaxFieldPerTable - 1) do
      begin
        MyTFieldDefs.Add(Format('MyField_%.4d_123456789012345678', [i + 1] { max 31 chars } ), TFieldType.ftString, MyFieldsStringSize, false);
        //
        Memo1.Lines.Add('Field :' + MyTFieldDefs.Items[i].Name + ', size: ' + MyTFieldDefs.Items[i].Size.ToString);
      end;
      //
      MyTotalChars := MyRecordsSizeTotal(MyTFieldDefs);
      //
      if (MyTotalChars > MyTotalCharsPerRecord) then
      begin
        ShowMessage('Total record size (chars = bytes) excced 4.000 bytes' + sLineBreak + 'Total: ' + MyTotalChars.ToString);
      end else begin
        try
          if FileExists(Table1.TableName) then // deleting my old-file-DBF
          DeleteFile(Table1.TableName);
          //
          MyTTable.FieldDefs := MyTFieldDefs;
          MyTTable.CreateTable;
          //
          Table1.TableName := MyTTable.TableName;
          Table1.Open;
          //
          ShowMessage(          { }
          'Date time: ' + DateTimeToStr(now) + sLineBreak +          { }
          'DBF created: ' + Table1.TableName + sLineBreak +          { }
          'Fields created: ' + Table1.Fields.Count.ToString + sLineBreak +      { }
          'Fields total size: ' + MyRecordsSizeTotal(Table1.FieldDefs).ToString { }
          );
        except
          on E: Exception do
          ShowMessage('My error:' + sLineBreak + E.Message);
        end;
      end;
    finally
      MyTFieldDefs.Free;
    end;
  finally
    MyTTable.Free;
  end;
end;

initialization

ReportMemoryLeaksOnShutdown := true;

finalization

end.
此帖子包含附件:
PNG 图像
大小:53.5K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行85.9375毫秒 RSS