Delphi Rio 10.3.2 Android FireDa c SQLITE не может открыть запрос - тот же код работал с Delphi Токио с тем же устройством android - PullRequest
0 голосов
/ 26 января 2020

Вот очень простой код, который отлично работал при компиляции с Delphi Токио:

procedure TfData.DataSend(Memo : TMemo);
var SelectQuery : string;
begin
    // Query simplified, more fields are retreived in original code, but same problem with simple query
    SelectQuery := 'SELECT NUM as "NUM::TEXT" FROM TRACE WHERE DT_SENT is null ORDER BY DT_TRACE';
    YsDbQuerySelect.SQL.Clear;
    YsDbQuerySelect.SQL.Add(SelectQuery);
    YsDbQuerySelect.Prepare;
    try
      YsDbQuerySelect.Open;
      if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
        YsDbQuerySelect.First; // ********** Exception !

        while not YsDbQuerySelect.eof do begin    
         // making a file... code removed, not relevant          
          YsDbQuerySelect.Next;
        end;
        YsDbQuerySelect.Close;
      end
      else begin
        YsDbQuerySelect.Close;
        MesInfo('No data to send');
      end;
    except
      on e : exception do begin
        // Exception displays the annoying error
        MesError(e.Message + ' SLQ : ' + SelectQuery);
      end;
    end;
end;

Тот же самый простой код, работающий на том же реальном android устройстве (Zebra TC25), больше не работает при компиляции с Токио 10.3.2. Метод «RecordCount» возвращает 6, однако «Первый» метод вызывает исключение: что-то вроде «Невозможно выполнить эту операцию над закрытым набором данных», исходное сообщение на французском языке: «Невозможно выполнить действие в ансамбле де données fermé "

Я не могу понять, как" RecordCount "может что-то вернуть, пока" First "вызывает это исключение. И в базе данных действительно 6 записей. Я тоже удалил потом воссоздал их. Та же ошибка. Я пытался поиграть с некоторыми опциями (выборки и т. Д.), Но ничего не получалось. Это действительно раздражает.

Также обратите внимание, что другие операции работают в той же базе данных SQLite правильно. Устройство может добавлять и удалять записи, используя TDFCommand, и отображать их, используя TDataSource. Только TDFQuery обнаруживает ошибку.

Ответы [ 2 ]

1 голос
/ 26 января 2020

В идеале вы должны переписать свой код как

YsDbQuerySelect.Open;
while not YsDbQuerySelect.eof do begin    
  // making a file... code removed, not relevant          
  YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;

. Причина в том, что

if YsDbQuerySelect.RecordCount > 0 then begin 
  YsDbQuerySelect.First

совершенно не требуется, потому что: а) если запрос возвращает ноль записей, YsDbQuerySelect.eof немедленно вернет значение False, поэтому while l oop никогда не выполнится и б) если запрос действительно вернет какие-либо записи, курсор набора данных FDQuery будет на первой записи, поэтому вызов значение First является излишним.

В любом случае, в целом плохая практика - делать поведение набора данных, подобное TQuery, зависимым от его переменной RecordCount, поскольку оно может быть ненадежным и крайне неэффективным, поскольку может вызвать набор данных для извлечения всех совпадающих записей.

Если вам абсолютно необходимо проверить, что запрос возвращает записи и, если это не так, отправить сообщение пользователю, просто замените

if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
  YsDbQuerySelect.First; // ********** Exception !
[etc]

на

if not YsDbQuerySelect.Eof then begin
  // your while not eof loop
end
else begin
  MesInfo('No data to send');
end;

Кстати, я не думаю, что вы должны рассматривать то, что вы описываете в своем собственном ответе, как решение проблемы, потому что если поведение, которое вы получаете, так как из-за повреждения файла .DFM (в чем я сомневаюсь), это может так же легко произойти снова.

0 голосов
/ 26 января 2020

Я удалил компонент TDFQuery, а затем сбросил новый. Это немного странно, но это работает. Я думаю, что нет ничего общего с Delphi Рио, но с поврежденным файлом?

...