Переменная iRecords без изменений после выполнения функции DbiWriteBlock - PullRequest
0 голосов
/ 06 сентября 2018

Значение переменной iRecords не изменяется после выполнения функции DbiWriteBlock. Пожалуйста, объясни мне это. Спасибо!

Это мой код:

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;

1 Ответ

0 голосов
/ 11 сентября 2018

Пояснение:

Переменная 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() для заполнения значений полей.

Ниже приведена документация из файла справки BDE:

Определение функции:

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

Описание:

DbiWriteBlock записывает блок записей в таблицу, связанную с HCURSOR.

Параметры:

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 для указанного количество пиРекорд DbiWriteBlock может получить доступ к данным в блоках большего размера чем 64 КБ, в зависимости от размера, который вы выделяете для буфера.

Примечание:

Эту функцию нельзя использовать, если записи содержат непустые большие двоичные объекты.

Парадокс:

Эта функция проверяет любые требования к ссылочной целостности или проверки достоверности, которые могут быть на месте. Если что-то не получается, напишите операция отменена.

Состояние завершения:

Курсор расположен на последней вставленной записи.

Результат:

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
...