Delphi Firedac SQLite коммит - PullRequest
       8

Delphi Firedac SQLite коммит

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

Когда я делал коммит, я наивно полагал, что физический файл базы данных будет обновлен (с изменением даты модификации), но, очевидно, он так не работает. Физический файл базы данных изменяется, когда база данных закрыта !!!

я написал небольшое тестовое приложение с (delphi 10.2.3) * FDConnection1: TFDConnection; (все настройки по умолчанию) (cachedupdate имеет значение false) * FDQuery1: TFDQuery; (все настройки по умолчанию)

Моя база данных SQLite содержит только одну таблицу CREATE TABLE t_stritems (IdItels INTEGER, St01 VARCHAR (200), St02 VARCHAR (200), St03 VARCHAR (200), ПЕРВИЧНЫЙ КЛЮЧ (IdItels))

Мой код очень прост

Подключить базу данных:

  FDConnection1.Connected := false;
  FDConnection1.Params.Clear;
  FDConnection1.Params.Add('DriverID=SQLite');
  FDConnection1.Params.ADD('Database=' + Edit1.text);
  FDConnection1.Connected := true;

Вставить строки в базу данных

FDQuery1.Connection := FDConnection1;
FDQuery1.close;
fdquery1.sql.clear;
fdquery1.sql.add('DELETE FROM t_stritems');

FDConnection1.StartTransaction;
fdquery1.ExecSQL;
FDConnection1.Commit;

fdquery1.sql.clear;
fdquery1.sql.add('SELECT * FROM t_stritems');
fdquery1.Open;
for i := 0 to 15 do
  begin
    for j:= 1 to 2000 do
      begin
        FDQuery1.append;
        FDQuery1.FieldByname('IdItels').asInteger := (i*2000) + j;
        FDQuery1.FieldByname('St01').asString := 'Text 01 Number : ' + FDQuery1.FieldByname('IdItels').asString;
        FDQuery1.FieldByname('St02').asString := 'Text 02 Number : ' + FDQuery1.FieldByname('IdItels').asString;
        FDQuery1.FieldByname('St03').asString := 'Text 03 Number : ' + FDQuery1.FieldByname('IdItels').asString;
        FDQuery1.post;
      end;
//    FDConnection1.Commit;
  end;
end;

Процесс тестирования: Подключите базу данных: (файл t_stritems моей базы данных содержит 32000 записей; размер файла базы данных составляет 2338 ko) После удаления sql, я имею в каталоге моего файла базы данных файл журнала (xxxx.db-journal). размер файла базы данных 2338 ko после первого коммита у меня всегда есть в каталоге моего файла базы данных файл журнала (xxxx.db-journal). размер файла базы данных 2338 ko (без физического обновления) Затем программа добавляет 32000 записей Дата изменения файла (.db) базы данных будет изменена только тогда, когда я оставлю свою заявку. !!! файл журнала (.db-log) будет удален в конце моего приложения

Вопросы: Как заставить коммит сохранить данные в базу данных? Это нормально ? Что физический файл базы данных изменяется только при закрытии приложения (и одновременно с подключением)?

Заранее спасибо за ответ С наилучшими пожеланиями Ромуальд

1 Ответ

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

Кажется, вы не понимаете, как использовать базы данных в Delphi.

1) Прежде всего вам необходимо добавить в свой код команду try / finally, чтобы перехватывать любые исключения и предотвращать утечки памяти.

2) Использовать connection.StartTransaction - connection.Commit в паре.

3) Фиксация должна использоваться в конце вашего цикла.Когда вы заканчиваете с обновлением ваших данных, вы вызываете Commit, чтобы выполнить все обновления, которые вы сделали на своих полях.

Вот как я бы переписал ваш код для реализации моих предложений выше:

  FDConnection1.Connected := false;
  FDConnection1.Params.Clear;
  FDConnection1.Params.Add('DriverID=SQLite');
  FDConnection1.Params.Add('Database=' + 'Edit1.text');
  FDConnection1.Connected := true;
  FDQuery1.Connection := FDConnection1;
  // your first transaction
  // just use ExceSQL directly to run your SQL query
  FDQuery1.ExecSQL('DELETE FROM t_stritems');
  try
    // start your transaction and use query.Open()
    FDConnection1.StartTransaction;
    FDQuery1.Open('SELECT * FROM t_stritems');
    for i := 0 to 15 do
      begin
        for j := 1 to 2000 do
          begin
            FDQuery1.FieldByName('IdItels').asInteger := (i * 2000) + j;
            FDQuery1.FieldByName('St01').AsString := 'Text 01 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
            FDQuery1.FieldByName('St02').AsString := 'Text 02 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
            FDQuery1.FieldByName('St03').AsString := 'Text 03 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
            FDQuery1.Post();
          end;
        // Dont use Commit inside loop. You should call Commit after you loop logic
        // FDConnection1.Commit;
      end;
    FDConnection1.Commit;
  finally
    FDConnection1.Close();
    FDQuery1.Free();
    FDConnection1.Free();
  end;
...