Форум: "Базы";
Текущий архив: 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