Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.08;
Скачать: CL | DM;

Вниз

Работа с Insert Into...Values с использованием потоков   Найти похожие ветки 

 
NotGooDP ©   (2006-08-01 10:59) [0]

Знающие люди, здравствуйте...
Проблема состоит в следующем:
При копировании информации (порядка 1 млн.записей), программа никак не реагирует на действия пользователя, понятно что копирование выполняется и после завершения копирования (~15-45мин ) опять отвисает, чтобы успокоить пользователя необходимо использовать ProgressBar...
т.е. Необходимо каким-то образом обновлять этот самый ProgressBar во время копирования информации.
Я предполагаю как это можно сделать (скорее всего с помощью выделения потока для копирования информации), но осуществить сей механизм у меня не получается бьюсь уже 3 день, ПОМОГИТЕ ПОЖАЛУЙСТА...


 
Johnmen ©   (2006-08-01 11:03) [1]

Если это выполняется одной командой типа INSERT INTO ... SELECT FROM ..., то получить достоверные данные о процессе выполнения представляется затруднительным.
Если же последовательностью команд типа INSERT INTO ..., то достаточно вставить ProcessMessage после обновления ProgressBar. Доп.поток не нужен.


 
ANB ©   (2006-08-01 11:04) [2]

Поставь каждые 1000-10000 записей (экспериментально подбери)

ProgressBar.StepIt;
Application.ProcessMessages;

И будет тебе счастье. А с отдельным потоком огребешь дополнительные проблемы (они решаются, но сильно прямыми руками :) ).
Заодно сможешь и кнопку "Стоп" прикрутить.


 
Сергей М. ©   (2006-08-01 11:16) [3]


> Необходимо каким-то образом обновлять этот самый ProgressBar


Через каждые N скопированных записей вычисляй и устанавливай очередное значение св-ва ProgressBar.Position, после чего вызывай ProgressBar.Update.
Пользовательский ввод при этом будет по-прежнему "заморожен" (что не позволит ему прервать операцию, если это нежелательно), но прогресс операции будет виден юзеру.


 
NotGooDP ©   (2006-08-01 11:29) [4]

Спасибо, за внимание, проявленное к моему вопросу, НО
возникает встречный вопрос...
Каким образом отслеживать эти N записей....
это как раз и есть основной вопрос наверное...
т.к. после ExecSQL начинается выполнение копирования и все...программа отвисает только после завершения процесса копирования

доп.инф. С БД соединяюсь с помощью ADO


 
Ega23 ©   (2006-08-01 11:29) [5]

Как вариант - делать это в цикле порциями Insert into Select top 1000 from ...
После каждой порции - отписывать результат во временную таблицу. А другим потоком - читать этот результат. Только таблица должна быть вида ##temp.


 
Sergey13 ©   (2006-08-01 11:34) [6]

2 [4] NotGooDP ©   (01.08.06 11:29)
>т.к. после ExecSQL начинается выполнение
Если иллюстрировать свои слова кодом, то меньше будет гаданий и больше конструктива.


 
NotGooDP ©   (2006-08-01 11:40) [7]


function TdmDataModule.SaveInfoLoadingMobile(aFileName: string;
     aLoad_data_all_records,
     aLoad_data_loading_records, aLoad_data_update_records,
     aLoad_data_insert_records: Integer): Boolean;
begin
 Result := False;
 With ADOQueryInsertMobile do begin
   Active := False;
   Parameters.FindParam("Load_data_filename").Value := aFileName;
   Parameters.FindParam("Load_data_all_records").Value := аLoad_data_all_records;
   Parameters.FindParam("Load_data_loading_records").Value := aLoad_data_loading_records;
   Parameters.FindParam("Load_data_update_records").Value := aLoad_data_update_records;
   Parameters.FindParam("Load_data_insert_records").Value := aLoad_data_insert_records;
   try
     ExecSQL;
     Result := True;
   except
   end;
 end;
end;


Да и еще сразу скажу, программу разрабатывал не я, человек, который ее создавал и поддерживал уволился, мне поступило требованние сделать ProgressBar чтобы было видно процесс загрузки


 
NotGooDP ©   (2006-08-01 11:43) [8]

SQL запрос


INSERT INTO [dbo].[Load_data]
([Load_data_filename],
[Load_data_all_records], [Load_data_loading_records],
[Load_data_update_records], [Load_data_insert_records])
VALUES(:Load_data_filename,
:Load_data_all_records,
:Load_data_loading_records,
:Load_data_update_records,
:Load_data_insert_records)


 
Sergey13 ©   (2006-08-01 11:44) [9]

> [7] NotGooDP ©   (01.08.06 11:40)
А сам запрос?


 
NotGooDP ©   (2006-08-01 11:52) [10]

SQL запрос цифрой [8]


 
Ega23 ©   (2006-08-01 11:59) [11]

Оберни хранимой процедурой, в качестве параметра передавай размер порции.


 
Плохиш ©   (2006-08-01 12:02) [12]


> NotGooDP ©   (01.08.06 11:40) [7]

А теперь ещё надо бы привести цикл в котором вызывается функция SaveInfoLoadingMobile и тогда тебе конкретно ткнут пальцем туда, куда надо вставить ProcessMessages.


 
zdm ©   (2006-08-01 12:06) [13]

http://uchenik.vofka.ru/index.php?dpt=3&CID=3&ID=24


 
NotGooDP ©   (2006-08-01 12:07) [14]

Да нет никакого цикла,есть кнопочка загрузить ))))), при нажатии вызываеться SaveInfoLoadingMobile...
тогда другой вопрос каким образом мне отслеживать позицию на которой прекратилось копирование????

П.С. извиняйте за уже столь тупые вопросы, но у меня 3 проекта и мое основное напрвление никак не SQL )))


 
zdm ©   (2006-08-01 12:07) [15]

почитай , запускай в отдельном потоке и контролируй


 
Плохиш ©   (2006-08-01 12:10) [16]


> NotGooDP ©   (01.08.06 12:07) [14]
> Да нет никакого цикла,есть кнопочка загрузить

О, так и представляю пользователя нажимающего кнопочку порядка 1 млн. раз 8-O


 
NotGooDP ©   (2006-08-01 12:21) [17]

механизм копирования предусматривает копирование сразу всей нформации
из файла в БД насколько я понимаю....-))

П.С. блин оффтопик какойта ... подскажите мне алгоритм пожалуйста и я скажу всем огромное спасибо )


 
Stanislav ©   (2006-08-01 14:20) [18]

Если используете ADO то в ExecuteOption включите AsyncExecute


 
NotGooDP ©   (2006-08-01 14:49) [19]

2 Stanislav ©
самое интересное что я уже включил данную опцию, все равно не помогает...программа так-же внешне находиться в повисшем состоянии

мне необходимо какимто образом копировать N записей , затем обновлять ProgressBar, затем продолжать копирование исключая уже скопированные N записей...


 
Neo Trinitron ©   (2006-08-01 14:58) [20]

Обычно такие задачи решаю так:

1. Запрос запускаю в потоке;
2. На время работы потока запускаю анимацию.

Пользователь видит что прога жива, статус бар пишет типа "подождите...", прогу можно свернуть, передвинуть и пр. Всегда удовлетворяло пользователей. А если хотят прогрессбар, то фраза "это уменьшит быстродействие и менее надёжно" должна помочь. ИМХО. Совет от первого лица.


 
DmiSb   (2006-08-01 15:02) [21]

2 NotGooDP
А откуда беруться данные ?

Пример при загрузке из файла

 StrL:=TStringList.Create;
 StrL.LoadFromFile(...);
 
 for i:=0 to StrL.Count-1 do begin
     ......Insert;

     ......Post;

     if (i*100 div StrL.Count-1 > ProgressBar.Position) then begin
       ProgressBar.Position := i*100 div StrL.Count-1;
       Application.ProcessMessages;
     end;
   end;

 ProgressBar.Position:=0;
 StrL.Free;

Миллион записей не грузил, но сотни тысяч запросто


 
NotGooDP ©   (2006-08-01 15:05) [22]

2 Neo Trinitron ©
Анимацию делал, не устраивает заказчика )))
до быстродействия им похоже нет особого дела
его (Заказчика) интересует непосредственно ProgressBar, хотя мне и не понятно ТАКОЕ желание, но заказчик врод как всегда прав )


 
Neo Trinitron ©   (2006-08-01 15:08) [23]

NotGooDP, сочувствую... Тогда можно в потоке, по частям.


 
NotGooDP ©   (2006-08-01 15:31) [24]

2 Neo Trinitron

> Тогда можно в потоке, по частям

обьясни пожалуйста поподробнее ...
Копирование происходит из Access файла, индексированных полей нет

я уже просто запарился....

да и еще на счет анимации не сразу увидел

> прогу можно свернуть, передвинуть и пр.

видимо я сделал чтото не так, у меня прога не передвигалась и анимация переставала работать когда тыркаеш на окно программы

если не сложно можешь привести пример...


 
Neo Trinitron ©   (2006-08-01 15:53) [25]

Значение какого-то поля поделить на диапазоны, желательно и проще равные. Эти диапазоны будут определять краевые условия запросов - частей. А поток...так он и в африке поток. Класс TThread юзать нужно. А рисование прогрессбара как и других контролов нужно синхронизировать.


 
NotGooDP ©   (2006-08-01 16:24) [26]

Всем спасибо, проблема разрешилась...


 
Slym ©   (2006-08-02 05:34) [27]

Попробуй так и засеки время...
function TdmDataModule.SaveInfoLoadingMobile(aFileName: string;
    aLoad_data_all_records,
    aLoad_data_loading_records, aLoad_data_update_records,
    aLoad_data_insert_records: Integer): Boolean;
begin
Result := False;
With ADOQueryInsertMobile do begin
  Active := False;
  Parameters.FindParam("Load_data_filename").Value := aFileName;
  Parameters.FindParam("Load_data_all_records").Value := аLoad_data_all_records;
  Parameters.FindParam("Load_data_loading_records").Value := aLoad_data_loading_records;
  Parameters.FindParam("Load_data_update_records").Value := aLoad_data_update_records;
  Parameters.FindParam("Load_data_insert_records").Value := aLoad_data_insert_records;
  try
    //ExecSQL;
    Result := True;
  except
  end;
end;
end;

если убрать бадягу с Parameters.FindParam("Load_data_filename") то твой код будет быстрее на засеченное время
Params:array[0..4] of TParameter;

Params[0]:=Parameters.FindParam("Load_data_filename");
а в цикле Params[0].Value:=aFileName;
можно ADOQuery заменить на ADOCommand и поставить Prepared:=true;


 
Anatoly Podgoretsky ©   (2006-08-02 19:56) [28]

У тебя просто зависает запрос, не может одна запись долго вставляться.



Страницы: 1 вся ветка

Текущий архив: 2006.10.08;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.029 c
2-1158864988
vegarulez
2006-09-21 22:56
2006.10.08
Запись результата select`a в переменную...


15-1158480993
Весь в делах
2006-09-17 12:16
2006.10.08
Разработка


1-1156861286
cod3r
2006-08-29 18:21
2006.10.08
ComPort Library - работа с com-портом


1-1156399727
tButton
2006-08-24 10:08
2006.10.08
рендеринг кучи текста


2-1158733722
TrainerOfDolpins
2006-09-20 10:28
2006.10.08
Как приложению узнать, где его exe-файл?