【问题标题】:iRecords variable no change after execute DbiWriteBlock function执行 DbiWriteBlock 函数后 iRecords 变量没有变化
【发布时间】:2018-09-06 12:13:55
【问题描述】:

执行 DbiWriteBlock 函数后 iRecords 变量的值没有变化。请给我解释一下。谢谢!

这是我的代码:

procedure TMainForm.btnBDICheckClick(Sender: TObject);
var
  Table       : TTable;
  PTable      : PByte;
  RecordSize  : Integer;
  RecordCount : Integer;
  iRecords    : Integer;
begin
  Table              := TTable.Create(Self);
  Table.DatabaseName := 'D:\Temp';
  Table.TableName    := 'SrcTable.db';
  Table.Active       := True;

  RecordSize  := Table.RecordSize;
  RecordCount := Table.RecordCount;

  PTable   := nil;
  iRecords := 0;

  GetMem(PTable, RecordSize * RecordCount);
  DbiWriteBlock(Table.Handle, iRecords, PTable);

  // iRecords = 0 at here

  Table.Close;
end;

【问题讨论】:

  • BDE API 已被弃用、存在漏洞、文档记录不佳且源代码封闭。我不知道有任何文档可以涵盖这一点。假设 iRecords 是一个 var 参数,您可能已经假设它应该被设置?那是你的问题吗?还是写不出来? (悖论表没有写入。)为什么要在 2018 年使用 BDE 编写新代码?
  • @WarrenP: - 我有一个使用 BDE 的 delphi 源代码,我想将它迁移到 ADO。所以,我必须了解 DbiWriteBlock 方法(输入、处理、输出)。 - 我调试了一下,看到iRecords(var)的值没有变化,源代码也没有错误,表是有效的。
  • 我认为您不必使用未记录(可能已损坏)的 API 调用来迁移 BDE。

标签: delphi bde


【解决方案1】:

变量iRecords 是指向要写入的记录数的指针。在输出时,iRecords 将写入实际记录数。您的代码应如下所示:

procedure TMainForm.btnBDICheckClick(Sender: TObject);
var
  Table       : TTable;
  PTable      : PByte;
  RecordSize  : Integer;
  RecordCount : Integer;
  iRecords    : Integer;
begin
   Table              := TTable.Create(Self);
   Table.DatabaseName := 'D:\Temp';
   Table.TableName    := 'SrcTable.db';
   Table.Active       := True;

   RecordSize  := Table.RecordSize;
   RecordCount := Table.RecordCount;

   //PTable   := nil;
   //iRecords := 0;

   iRecords := RecordCount;
   GetMem(PTable, RecordSize * RecordCount);
   DbiWriteBlock(Table.Handle, iRecords, PTable);

   Table.Close;
   ShowMessage('Records: ' + IntToStr(iRecords));
end;

使用此代码,您将添加空记录。使用DbiInitRecord()DbiPutField() 填充字段值。

以下是关于 DbiWriteBlock 函数的文档(来自 BDE 帮助文件):

函数定义:

function DbiWriteBlock (hCursor: hDBICur; var iRecords: Longint; pBuf: Pointer): DBIResult stdcall;

说明:

DbiWriteBlock 将记录块写入与关联的表中 h光标。

参数:

hCursor Type: hDBICur (Input) Specifies the cursor handle to the table.
piRecords Type: pUINT32 (Input/Output) On input, piRecords is a pointer to the number of records to write. On output, pointer to the client variable that receives the actual number of records written. The number actually written may be less than requested if an integrity violation or other error occurred.
pBuf Type: pBYTE (Input) Pointer to the buffer containing the records to be written.

用法:

这个函数类似于为指定的调用 DbiAppendRecord piRecords 的数量。 DbiWriteBlock 可以访问更大的块中的数据 大于 64Kb,具体取决于您为缓冲区分配的大小。

注意:

如果记录中包含非空 BLOB,则不能使用此函数。

悖论:

此功能验证任何参照完整性要求或 可能进行的有效性检查。如果任一失败,则写入 操作被取消。

完成状态:

光标位于最后插入的记录处。

结果:

DbiResult                   Meaning
DBIERR_NONE                 The block of records contained in pBuf has been successfully written to the table specified by hCursor.
DBIERR_INVALIDHNDL          The specified cursor handle is invalid or NULL, or piRecords is NULL, or pBuf is NULL.
DBIERR_TABLEREADONLY        The table is opened read-only; cannot write to it.
DBIERR_NOTSUFFTABLERIGHTS   Insufficient table rights to insert a record. (Paradox only.)
DBIERR_NODISKSPACE          Insertion failed due to insufficient disk space.

Delphi 7 帮助示例:

procedure fDbiWriteBlock(Customer: TTable; var RecordsToInsert: Longint);

var
  pRecordsBuf, pTmpBuf: pBYTE;
  Rec: Longint;
  CustNo: Double;
begin
  Randomize;
  GetMem(pRecordsBuf, Customer.RecordSize * RecordsToInsert);
  pTmpBuf := pRecordsBuf;
  try
    for Rec := 1 to RecordsToInsert do begin
      CustNo := Random(1000000);
      // Iterate through the entire record buffer filling each
      // individual record with information
      with Customer do begin
        Check(DbiInitRecord(Handle, pTmpBuf));

        Check(DbiPutField(Handle, FieldByName('CustNo').Index + 1, pTmpBuf,
          pBYTE(@CustNo)));
        Check(DbiPutField(Handle, FieldByName('Company').Index + 1, pTmpBuf,
          PChar('INPRISE Corporation')));
        Inc(pTmpBuf, RecordSize);
      end;
    end;
    Check(DbiWriteBLock(Customer.Handle, RecordsToInsert, pRecordsBuf));
  finally
    FreeMem(pRecordsBuf, Customer.RecordSize * RecordsToInsert);
  end;
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 2023-01-30
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多