Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];

Вниз

Работа с 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.046 c
6-1147551210
w!zard
2006-05-14 00:13
2006.10.08
icq и цепочка прокси


15-1158163659
OSokin
2006-09-13 20:07
2006.10.08
День Программиста


2-1159103648
Серый
2006-09-24 17:14
2006.10.08
Текстовые поля


15-1158402494
Чапаев
2006-09-16 14:28
2006.10.08
bash.org.ru ;-)


2-1158408359
greengeneral
2006-09-16 16:05
2006.10.08
Как сделать чтобы в Edit1 можно было вводить только цифры?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский