найти максимальное значение в базе данных с Delphi - PullRequest
0 голосов
/ 13 ноября 2018

Я работаю с Delphi 2010. У меня есть база данных Microsoft Access с именем tblUserInfo, в ней есть поле с именем NUMOFREPORTS, содержащее 11 чисел. Мне нужно выполнить поиск по элементам данных, найти максимальное число и сохранить его в переменной. Мой план состоял в том, чтобы присвоить значения в базе данных массиву целых чисел, а затем отсортировать массив, чтобы найти максимум.

Это то, что я имею до сих пор:

i:=1;
while NOT tblUserInfo.eof do
begin
  arrNumOfReps[i]:= tblUserInfo['NUMOFREPORTS'];
  tblUserInfo.Next;
  INC(i);
end;

NumOfReps:= arrNumOfReps[1];
for I := 1 to length(arrNumOfReps) do
begin
  if arrNumOfReps[i] > NumOfReps then
  begin
    NumOfReps:= arrNumOfReps[i];
  end;
  showmessage(inttostr(NumOfReps));
end;

Когда я запускаю программу, она не работает и прерывается на NumOfReps:= arrNumOfReps[1];, и я получаю сообщение об ошибке «Access access».

Есть ли у кого-нибудь какие-либо исправления в моем коде или альтернативных решениях? Спасибо

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Как было отмечено MartynA в комментариях, вы должны позволить базе данных найти вам максимальное значение, а не сначала извлекать все значения, а затем искать максимальное значение самостоятельно. Почему?

  1. В вашем случае вы утверждаете, что у вас есть только 11 значений в этом поле, поэтому получение данных из базы данных не составит труда. Но что если у вас там будет миллион ценностей? Извлечение значений 1M из базы данных может обременительно для базы данных, а также потребует значительного объема памяти на клиентском компьютере, если вы сохраните эти значения в массиве для дальнейшей обработки (поиск максимального значения).
  2. База данных наверняка сможет найти максимальное значение гораздо быстрее, чем вы, поскольку она может легко разделить эту задачу между несколькими ядрами. Не говоря уже о том, что, если это конкретное поле проиндексировано, база данных, скорее всего, уже имеет максимальное значение, сохраненное как одно из значений индекса, и в этом случае база данных может вернуть максимальное значение мгновенно. И даже если максимальное значение не хранится напрямую, поскольку одна из баз данных значений индекса будет проверять только часть записей, а не проверять каждую из них.

И если по какой-то особой причине вы действительно не можете использовать встроенную функцию базы данных Select Max (возможно, значение хранится не в виде числового значения, а в виде специальной строки, а максимальное значение определяется некоторой частью в середине строка) и вы должны действительно найти максимальное значение самостоятельно, не беспокойтесь о сохранении всех значений в массиве. Вместо этого сделайте необходимое сравнение для непосредственного нахождения максимального значения при извлечении записей из базы данных. Возможно, что-то вроде этого, где я только что изменил ваш цикл для извлечения записей из базы данных:

while NOT tblUserInfo.eof do
begin
  if tblUserInfo['NUMOFREPORTS'] > NumOfReps then
  begin
    NumOfReps:= tblUserInfo['NUMOFREPORTS'];
  end;
  tblUserInfo.Next;
end;
0 голосов
/ 14 ноября 2018

Как вы объявили свой массив?Исходя из того, как вы работаете с ним, его, вероятно, следует объявить так:

var
  ArrNumOfReps: array[1..12] of Integer;

Но это ограничено, поскольку программа поддерживает максимум 11 значений.Вместо этого используйте динамический массив

var
  ArrNumOfReps: array of Integer;

i:=0;
while NOT tblUserInfo.eof do
begin
  SetLength(ArrNumOfReps, Length(ArrNumOfReps) + 1);
  arrNumOfReps[i]:= tblUserInfo.FieldByName('NUMOFREPORTS').AsInteger;
  tblUserInfo.Next;
  INC(i);
end;

Это позволит программе работать с переменным числом повторений.

...