Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/22: Рейтинг темы: голосов - 22, средняя оценка - 4.68
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 133
1
MS Access

Многопоточная запись в базу данных access

25.10.2019, 22:06. Показов 4249. Ответов 32

Author24 — интернет-сервис помощи студентам
друзья столкнулся с такой ситуацией пишу в потоках данные в таблицу через adoquery. В итоге данные в таблице перемешаны, есть ли способ писать данные по порядку?
NAddTimeNumItem
225.10.2019 21:22:591
925.10.2019 21:22:591
825.10.2019 21:22:591
1025.10.2019 21:22:591
325.10.2019 21:23:002
1225.10.2019 21:22:591
225.10.2019 21:22:592
725.10.2019 21:23:002
425.10.2019 21:23:002
625.10.2019 21:23:002
1025.10.2019 21:23:003
1225.10.2019 21:23:002
825.10.2019 21:23:015
1125.10.2019 21:23:002
325.10.2019 21:23:015
925.10.2019 21:23:015
925.10.2019 21:23:016
525.10.2019 21:23:017
525.10.2019 21:23:018
для теста использую следующую конструкцию:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
implementation
 
{$R *.dfm}
var
 Potoks: array [1..12] of TPotok;
 n:integer;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
for n:=1 to 12 do
begin
Potoks[n]:=TPotok.Create(n);
 
end;
end;
 
constructor TPotok.Create(i:integer);
begin
Cnt:=i;
inherited Create(False);
FreeOnTerminate:=True;
end;
 
procedure TPotok.Execute;
var
Q:TADOQuery;
t:integer;
begin
CoInitialize(nil);
try
Form1.Label1.Caption := inttostr(Cnt);
Q:=TADOQuery.Create(Application);
Q.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\shar\multyaccessADO\ADO\thread.mdb; Persist Security Info=False;Jet OLEDB:Database Password=""';
try
for t:=1 to 1000 do
  begin
  Q.Close;
  Q.SQL.Clear;
  Q.SQL.Add('INSERT INTO Example (N, AddTime, NumItem) VALUES ("'+IntToStr(Cnt)+'","'+DateTimeToStr(Now)+'","'+IntToStr(t)+'")');
  Q.ExecSQL;
  end;
 
     finally
      Q.Free;
    end;
  finally
    CoUninitialize;
  end
end;
в гугле не нагуглил
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2019, 22:06
Ответы с готовыми решениями:

Нужно создать электронную запись на приём к врачу в Access базу данных, и сделать саму программу в delphi
Базу данных я уже сделал, но ещё нужно сделать электронную очередь в которой будет показываться уже...

Запись в базу данных Access
добрый день, не могу записать в базу данных, не понимаю в чем ошибка, на шарпе пишу не давно,...

Запись в базу данных Access
Здравствуйте. Делаю дипломный проект. Есть необходимость записать в БД Access данные. Использую C#,...

Запись в базу данных access
При попытке выполнения кода выдаёт ошибку "Ошибка синтаксиса в инструкции INSERT INTO" и...

32
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 133
13.11.2019, 01:35  [ТС] 21
Author24 — интернет-сервис помощи студентам
Скрин таблицы
Миниатюры
Многопоточная запись в базу данных access  
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 133
13.11.2019, 05:30  [ТС] 22
Ура заработало был косяк в таблице...
вот рабочий пример может кому нужно
скорость записи колоссальная я тестил 100000 записей
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
procedure TForm1.Button2Click(Sender: TObject);
var i : integer;
SW: TStopwatch;
begin
        SW:=TStopwatch.StartNew;
        SW.Start;
        Gauge1.MinValue := 0;
 
       DataModule2.FDQuery1.SQL.Text := 'insert into data values ( :p1, :p2, :p3, :p4, :p5, :p6, :p7, :p8, :p9)';
 
       DataModule2.FDQuery1.Params.Bindmode := pbByNumber;;
       DataModule2.FDQuery1.Params.ArraySize :=100000;
       Gauge1.MaxValue := DataModule2.FDQuery1.Params.ArraySize ;
       DataModule2.FDQuery1.Params[0].DataType := ftInteger;
      try
      for I := 0 to DataModule2.FDQuery1.Params.ArraySize-1 do
       begin
 
          DataModule2.FDQuery1.Params[0].Asintegers[i] := i;
          DataModule2.FDQuery1.Params[1].AsStrings[i] := 'Ok';
          DataModule2.FDQuery1.Params[2].AsDateTimes[i] := now;
          DataModule2.FDQuery1.Params[3].AsFloats[i]:= double(i) + 0.1 ;
          DataModule2.FDQuery1.Params[4].AsFloats[i]:= double(i) + 0.1 * 0.2;
          DataModule2.FDQuery1.Params[5].AsFloats[i]:= double(i) + 0.1 * 3;
          DataModule2.FDQuery1.Params[6].AsFloats[i]:= 1.0;
          DataModule2.FDQuery1.Params[7].AsIntegers[i]:= i * 3;
          DataModule2.FDQuery1.Params[8].AsStrings[i]:= 'Title';
          Gauge1.Progress := i;
      end;
        DataModule2.FDQuery1.Params.ArraySize := i;
        DataModule2.FDQuery1.Execute(DataModule2.FDQuery1.Params.ArraySize, 0);
        DataModule2.FDQuery1.Connection.Commit;
        SW.Stop;
        ShowMessage(IntToStr(DataModule2.FDQuery1.RowsAffected) + '\/'+SW.Elapsed.TotalMinutes.ToString);
      except
      on e:Exception do
      begin
        DataModule2.FDQuery1.Connection.Rollback;
        raise;
      end;
      end;
 
end;
Миниатюры
Многопоточная запись в базу данных access  
0
32 / 26 / 7
Регистрация: 18.10.2019
Сообщений: 187
13.11.2019, 09:33 23
Не надо заводить в SQLite своего поля счетчик, оно уже для каждой таблицы автоматом создается и называется RowID и автоматом получает индекс, просто скрыто от глаз, но обратится к нему можно.
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 133
13.11.2019, 12:41  [ТС] 24
Вы имеете ввиду если убрать столбец id полностью из таблицы? стоит в таблице а id как ключевое without для RowID
SQL
1
2
3
4
5
6
7
8
9
10
CREATE TABLE [DATA](
  [id] INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
  [namep] TEXT, 
  [datet] DATETIME, 
  [pressure1] DOUBLE, 
  [pressure2] DOUBLE, 
  [temperature] DOUBLE, 
  [depths] DOUBLE, 
  [tmp] INTEGER, 
  [title] TEXT) WITHOUT ROWID;
Или нужно по другому?
0
32 / 26 / 7
Регистрация: 18.10.2019
Сообщений: 187
13.11.2019, 12:58 25
Да, уберите эту инструкцию WITHOUT ROWID и свой столбец ID - он дублирует уже имеющийся RowID

Добавлено через 3 минуты
Просто в SQLite если выполнить запрос
SQL
1
SELECT * FROM AnyTable
вы получите записи без отображения RowID, а вот если явно указать:
SQL
1
SELECT RowID,* FROM AnyTable
то уже получите еще и идентификатор

Добавлено через 9 минут
Ну а для отображения именно нумерации записей по порядку (не путать с RowID), независимо от порядка сортировки есть специальная инструкция:
SQL
1
SELECT *, ROW_NUMBER() OVER(ORDER BY RowID) AS RowNo FROM AnyTable
только это счастье появилось относительно недавно и если у вас старая версия SQLite то там такого нет.
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 133
13.11.2019, 13:51  [ТС] 26
Благодарю
SQL
1
SELECT RowID,* FROM AnyTable
сделал как вы сказали получается более оптимально и скорость записи выросла из за отсутствия поля. в данном примере
SQL
1
[namep] TEXT, [title] TEXT
тоже лишние они будут в другой таблице в примере оставил просто

Добавлено через 51 минуту
Дополнительный вопрос ? а есть возможность использовать такую конструкцию для быстрой загрузки в DBchart?
Я использую так:
Delphi
1
2
3
4
5
6
 MainForm.ADOquery1.First;
  while not MainForm.ADOquery1.Eof do
    begin
    DBChart1.Series[i].AddXY(MainForm.adoquery1.FieldValues['datet'],MainForm.adoquery1.FieldValues['temperature'], '',clRed); //
    MainForm.ADOquery1.Next;
    end;
Delphi
1
2
3
ADOquery1
заменю на 
FDQuery1
0
32 / 26 / 7
Регистрация: 18.10.2019
Сообщений: 187
13.11.2019, 14:51 27
есть возможность использовать такую конструкцию для быстрой загрузки в DBchart
Конечно есть. Указываете ваш Query в качестве источника данных для series в DBchart, назначаете поля для Х и У и вроде все.

Добавлено через 31 минуту
Как я понял вам нумерация в запросе нужна для вывода порядкового номера значения? Для DBChart этого делать не надо, он сам нумерует значения по порядку, причем выводит на экран не все значения, а только то что на экран помещается.
А в коде настройка DBChart для отображения данных запроса очень проста:
Delphi
1
2
3
4
FDQuery1.SQL.Text := 'select YValue from AnyTable';
FDQuery1.Open;
Series1.DataSource := FDQuery1;
Series1.YValues.ValueSource := 'YValue';
1
2 / 2 / 0
Регистрация: 03.06.2018
Сообщений: 140
21.12.2023, 14:47 28
Цитата Сообщение от Signum7 Посмотреть сообщение
Ура заработало был косяк в таблице...
вот рабочий пример может кому нужно
скорость записи колоссальная я тестил 100000 записей
Подскажите, а работает ли такой механизм в Access?
0
3586 / 2195 / 693
Регистрация: 29.05.2013
Сообщений: 9,376
21.12.2023, 16:08 29
Цитата Сообщение от POJIBOX Посмотреть сообщение
Подскажите, а работает ли такой механизм в Access?
Если будете использовать для подключения к акцесу не Ado, а FDac, то должно и там работать. Попробуйте.

Добавлено через 1 минуту
В принципе можно и с Ado пачкой писать, там для этого есть режим BatchMode
0
2 / 2 / 0
Регистрация: 03.06.2018
Сообщений: 140
21.12.2023, 16:29 30
Цитата Сообщение от Пытливый Посмотреть сообщение
BatchMode
А можно поподробнее, в каком компоненте это посмотреть?

Цитата Сообщение от Пытливый Посмотреть сообщение
FDac
Я посмотрел на количество компонентов и свойства... Что-то там явно не на скорую руку рассчитано, или можно обойтись малой кровью при переходе с ADO?
0
3586 / 2195 / 693
Регистрация: 29.05.2013
Сообщений: 9,376
21.12.2023, 16:46 31
Для датасетов в Ado есть параметр LockType. По умолчанию он выставлен как ltOptimistic и в этом режиме запись в базу идет сразу после пост-команды, но если LockType=ltBatchOptimistic, то в этом случае запись в базу будет выполнена только после выполнения метода UpdateBatch. Это позволяет накопить пачку записей и записать их в базу одной командой. Я не помню, если там ограничение на это количество, но использование этого метода очень сильно может ускорить множественную вставку записей в базу.
1
2 / 2 / 0
Регистрация: 03.06.2018
Сообщений: 140
21.12.2023, 17:04 32
Цитата Сообщение от Пытливый Посмотреть сообщение
LockType=ltBatchOptimistic,
и курсор, как я понял, должен быть на стороне клиента, чтобы эта связка работала?
0
3586 / 2195 / 693
Регистрация: 29.05.2013
Сообщений: 9,376
21.12.2023, 17:06 33
Цитата Сообщение от POJIBOX Посмотреть сообщение
и курсор, как я понял, должен быть на стороне клиента, чтобы эта связка работала?
Вот этого не помню, читайте доки.

Добавлено через 1 минуту
Теоретически это совсем не обязательно, ведь они копятся в кэше клиента, а состояние курсора на каш клиента не может влиять.
0
21.12.2023, 17:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.12.2023, 17:06
Помогаю со студенческими работами здесь

запись из txt файла в базу данных Access
Здравствуйте, я не очень хорошо пока пишу на ASP, но мне на данный момент нужно решить такую...

Как программно добавить запись в базу данных access через datagridview?
Проблема заключается в следующем: Когда заполняю таблицу с клавиатуры, то данные с datagridview...

Запись в базу access ADO
база access подключаюсь через ADO если несколько человек работают с программой то при изменении...

Как заполнить базу данных Access с помощью vba в том же access и считать из нее инфу?
Прошу помочь в азах. Как заполнить базу данных Access с помощью vba в том же access и считать из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru