Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отправить много данных в MySQL одним потоком / 25 сообщений из 49, страница 1 из 2
19.07.2018, 14:05
    #39676183
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Пытаюсь в RAD Studio DX 10.2 считать данные из MSSQL данные и синхронизировать либо просто перекинуть в MySQL.
Данных около 50.000 записей (примерно7Мб). Использую TADOQuery и TADOConnection.
К обеим БД успешно подключился и из MSSQL получаю данные.
Из MSSQL имею либо многострочный файл на диске, либо TStringList наполненый данными.
Каждая строка файла - это одна запись данных,
либо
Каждая строка в TStringList'е - это одна запись данных.
Данные выглядят так:
Код: pascal
1.
INSERT INTO `database`.`db_table`(`ArtikelID`, `ManufacturerName`, `ManufacturerPN`, `Supplier`, `SupplierPN`, `Description`, `PhotoURL`, `Price`, `Quantity`, `Currency`, `Lagerplatz`) VALUES ('471', 'Analog Devices', 'AD780BRZ', 'Firma', '000000482', 'V-REF AD780BRZ  SO8 - AD780BRZ Analog Devices 8 ld SOIC', '-', '9,9', '0', 'EUR', '');


Поле "Description" имеет тип "текст" и содержит в себе текст (включая преносы строк).

Я не профи. Пользуюсь delphi изредка, потому заранее прошу прощения за возможные "элементарные" вопросы.

Хотелось бы одним циклом и без промежуточного сохранения на диск прогнать все данные одним потоком в MySQL.
С TStream не умею работать, но понимаю, что возможно тут это надо использовать.
Прошу, накидайте пример как действовать. Не забудьте что записей(инсёртов) много, и возможно надо делать считывание из TStringList и отправку в MySQL порциями.
...
Рейтинг: 0 / 0
19.07.2018, 14:18
    #39676194
чччД__
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001,

задача решается без привлечения Delphi. Иди в профильный (MS SQL) форум.
...
Рейтинг: 0 / 0
19.07.2018, 14:20
    #39676195
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
чччД__задача решается без привлечения Delphi. Иди в профильный (MS SQL) форум.
В гугле SSIS. При чем работает достаточно шустро со свистоперделками, салютами и застольями.
...
Рейтинг: 0 / 0
19.07.2018, 14:31
    #39676206
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Уже делал с помощью PowerShell и перегонял в Firebase,
но теперь концепция поменялась и при вытаскивании данных из MSSQL выполняется много хитрых запросов, чтобы получить в конечном итоге из сотен таблиц именно то что надо получить.
SSIS уже попробовал, но у него трудности с MySQL и как написал выше перед тем надо выполнить ещё кучу запросов.
Кроме того струкстура выглядит так:
Сервер1 - MSSQL
Сервер2 - мой написаный на Delphi сервис
Сервер3 - MySQL

Сервер1 и Сервер3 между собой не ладят, но Сервер2 имеет полный доступ на оба.

Сервис я уже сделал и извлекаю все данные, но осталось лишь отправить в мускл.
...
Рейтинг: 0 / 0
19.07.2018, 14:31
    #39676207
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Код: pascal
1.
2.
3.
4.
5.
while not SrcQuery.Eof do
  DestQuery.Params[..].Value := ScrQuery.Fields[..].Value
  ...
  DestQuery.Exec;
  SrcQuery.Next
...
Рейтинг: 0 / 0
19.07.2018, 14:34
    #39676209
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Тогда можно загнать одним скриптом:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
...
Рейтинг: 0 / 0
19.07.2018, 14:40
    #39676219
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Василий 2
Код: pascal
1.
2.
3.
4.
5.
while not SrcQuery.Eof do
  DestQuery.Params[..].Value := ScrQuery.Fields[..].Value
  ...
  DestQuery.Exec;
  SrcQuery.Next



Примерно так я и сам понимаю, тоже гуглил :)

Представьте, у меня есть заполненый TStringList,
но что надо вписать в качестве DestQuery.Params[..].Value и ScrQuery.Fields[..].Value ?
...
Рейтинг: 0 / 0
19.07.2018, 14:46
    #39676225
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
wadmanТогда можно загнать одним скриптом:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

Данные я действительно из MSSQL тоже могу сохранить в файл (как уже выше писал). Естати файл так и выглядит, как вы сейчас прислали, только таких 50.000 строк.
Но вот мои хотелки:
1. я хочу избежать потерь времени при записи в файл. Это просто ненужная операция.
2. хочу избежать промежуточных действий типа дополнительный скрипт или крон процесс для иморта сохранёного файла в MySQL.
...
Рейтинг: 0 / 0
19.07.2018, 14:48
    #39676232
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Василий 2
Код: pascal
1.
2.
3.
4.
5.
while not SrcQuery.Eof do
  DestQuery.Params[..].Value := ScrQuery.Fields[..].Value
  ...
  DestQuery.Exec;
  SrcQuery.Next



Кстати это легко вызовет
Код: html
1.
ERROR 1040 (08004): Too many connections



Так как 50.000 записей!
...
Рейтинг: 0 / 0
19.07.2018, 15:10
    #39676248
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001
Код: html
1.
Too many connections


Так как 50.000 записей !не вижу связи
...
Рейтинг: 0 / 0
19.07.2018, 15:19
    #39676255
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
авторwhile not SrcQuery.Eof do

Это проход по всем записям и мускл не успевает обрабатывать их принятие.


Мои вопросы остались не отвечеными.
...
Рейтинг: 0 / 0
19.07.2018, 15:33
    #39676267
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001Естати файл так и выглядит, как вы сейчас прислали, только таких 50.000 строк.
Не совсем. В моем примере мускульный вариант вставки сразу трех строк, а не одной. Можно и 100 строк одним махом вставить.
...
Рейтинг: 0 / 0
19.07.2018, 15:35
    #39676270
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
wadman,

ну, в моём 50.000 инсёртов.

Проблема остаётся открытой...
...
Рейтинг: 0 / 0
19.07.2018, 15:45
    #39676290
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Попробуй группировать инсёрты трансакциями. Например по тысяче за транзакцию. Глядишь, немного ускорится.

Ну и как wadman предлагал одним скриптом по тысяче записей тоже нормальная альтернатива транзакции.
Причём 1000 - это условное число - им можно поиграться в сторону уменьшения / увеличения.
...
Рейтинг: 0 / 0
19.07.2018, 15:50
    #39676294
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001ну, в моём 50.000 инсёртов.
Проблема остаётся открытой...1. Прочитали запись
2. Заполнили параметры запроса
Код: sql
1.
2.
3.
4.
5.
INSERT INTO `database`.`db_table`(
  `ArtikelID`, `ManufacturerName`, `ManufacturerPN`, `Supplier`, `SupplierPN`, `Description`, `PhotoURL`, `Price`, `Quantity`, `Currency`, `Lagerplatz`
) VALUES (
  :ArtikelID, :ManufacturerName, :ManufacturerPN, :Supplier, :SupplierPN, :Description, :PhotoURL, :Price, :Quantity, :Currency, :Lagerplatz
)


3. Выполнили запрос
4. Перешли к следующей записи MSSQL
5. GOTO 1
...
Рейтинг: 0 / 0
19.07.2018, 15:50
    #39676295
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
wadmanНе совсем. В моем примере мускульный вариант вставки сразу трех строк, а не одной. Можно и 100 строк одним махом вставить. Мне тут один бэкап попался Postgresql, так там оказывается в порядке вещей в SQL после INSERT CSV фигачить. За один INSERT можно легко сотню-другую тысяч записей вставить. Буквально за секунду. :D
...
Рейтинг: 0 / 0
19.07.2018, 16:09
    #39676309
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Ребята,

в следствии моего незнания "как надо правильно",
я сделал так:

Код: pascal
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.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
var
  ADOConn  : TADOConnection;
  ADOQuery : TADOQuery;
  DataSrc  : TDataSource;
  Param    : TParameter;
  SQLStr  : string;
  MyStream: TStream;

var tString,File2Use:string;
    count,i:integer;
    SuperQuery:TStringList;

begin

  with AdoQuery1 do
    begin
      SuperQuery := TStringList.Create;
     // MyStream:= TStream.Create;  
      DisableControls;
      First;

      while not (Eof) do begin  // читаю всё записи

      { SQL Query }    // создаю записи запросов  /// примерно 50.000 таких строк
      SuperQuery.Append('INSERT INTO `database`.`db_table`(`ArtikelID`,'+
            ' `ManufacturerName`, `ManufacturerPN`, `Supplier`, `SupplierPN`,'+
            ' `Description`, `PhotoURL`, `Price`, `Quantity`, `Currency`, `Lagerplatz`) VALUES'+
            ' ('''+''+trim(Fields.Fields[0].AsString)+
            ''', '''+trim(Fields.Fields[1].AsString)+
            ''', '''+trim(Fields.Fields[2].AsString)+
            ''', ''Firma'', '''+
                 trim(Fields.Fields[3].AsString)+
            ''', '''+trim(Fields.Fields[4].AsString)+
            ''', ''-'', '''+trim(Fields.Fields[5].AsString)+
            ''', '''+trim(Fields.Fields[6].AsString)+
            ''', ''EUR'', '''+trim(Fields.Fields[7].AsString)+''');');


         //SuperQuery.SaveToStream(MyStream);   // попытался через стрим
         //Memo1.Text:=SuperQuery.Text;

        Next;
      end;


  { Create an ADO connection. }
  ADOConn := TADOConnection.Create(Self);
  { Set up the provider engine }

  { Set up the connection string. }
  ADOConn.ConnectionString := Format(ConnString, [UserName, PassWord, Server]);

  { Disable login prompt. }
  ADOConn.LoginPrompt := False;

  try
    ADOConn.Connected := True;
  except
    on e: EADOError do
    begin
      MessageDlg('Error while connecting', mtError,
                  [mbOK], 0);

      Exit;
    end;
  end;

  { Create the query. }
  ADOQuery := TADOQuery.Create(Self);
  ADOQuery.Connection := ADOConn;
////  ADOQuery.SQL.LoadFromStream(MyStream);  // в этом варианте делаю что-то не так
//  ADOQuery.SQL.LoadFromFile('file.txt');   // этот вариант у меня не работает




  { Set the query to Prepared--it will improve performance. }
  ADOQuery.Prepared := true;

  try
  ADOQuery.ExecSQL;
//  SuperQuery.SaveToFile('file.txt');    // так могу сохранить в файл
//  ADOConn.Execute(SuperQuery.Text);  // так попытался закинуть все записи из TStringList
    ADOQuery.Active := True;
  except
    on e: EADOError do
    begin
      MessageDlg('Error while doing query', mtError,
                  [mbOK], 0);

      Exit;
    end;
  end;

end;



В приведеном исходнике вы можите видеть моё колдовство:
через ADOQuery.ExecSQL;
и через ADOConn.Execute();

Вот я дошёл до этого бреда и защёл в ступор. Не могу это разрулить.
...
Рейтинг: 0 / 0
19.07.2018, 16:21
    #39676320
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Можете видеть, как я сделал не очень хороший цикл и создаю убогим методом запрос-строку...
...
Рейтинг: 0 / 0
19.07.2018, 16:24
    #39676325
Tactical Nuclear Penguin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001Можете видеть, как я сделал не очень хороший цикл и создаю убогим методом запрос-строку...

какую строку?
вижу какой-то SuperQuery
который нигде не используется
что ты хочешь то?
...
Рейтинг: 0 / 0
19.07.2018, 16:25
    #39676326
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
используется, я просто закомментировал
Код: pascal
1.
ADOConn.Execute(SuperQuery.Text); 
...
Рейтинг: 0 / 0
19.07.2018, 16:30
    #39676329
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Код: pascal
1.
2.
через ADOQuery.ExecSQL;
и через ADOConn.Execute();



Смотрите на закомментированные строки слэшами //, это были мои варианты
...
Рейтинг: 0 / 0
19.07.2018, 16:32
    #39676333
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Блин, чтобы не разбираться в моём бреде, напишите свой вариант, потому что я точно что-то напутал
...
Рейтинг: 0 / 0
19.07.2018, 16:37
    #39676337
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
user00001
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 SuperQuery.Append('INSERT INTO `database`.`db_table`(`ArtikelID`,'+
            ' `ManufacturerName`, `ManufacturerPN`, `Supplier`, `SupplierPN`,'+
            ' `Description`, `PhotoURL`, `Price`, `Quantity`, `Currency`, `Lagerplatz`) VALUES'+
            ' ('''+''+trim(Fields.Fields[0].AsString)+
            ''', '''+trim(Fields.Fields[1].AsString)+
            ''', '''+trim(Fields.Fields[2].AsString)+
            ''', ''Firma'', '''+
                 trim(Fields.Fields[3].AsString)+
            ''', '''+trim(Fields.Fields[4].AsString)+
            ''', ''-'', '''+trim(Fields.Fields[5].AsString)+
            ''', '''+trim(Fields.Fields[6].AsString)+
            ''', ''EUR'', '''+trim(Fields.Fields[7].AsString)+''');');

Я же сказал и даже выделил
_Vasilisk_2. Заполнили параметры запросаНе сформировали заново SQL а заполнили параметры
...
Рейтинг: 0 / 0
19.07.2018, 16:43
    #39676341
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
AdoQueryMySQL.SQL.Text := 'INSERT INTO `database`.`db_table`(`ArtikelID`, `ManufacturerName`, `ManufacturerPN`,'+
              '`Supplier`, `SupplierPN`, `Description`, `PhotoURL`, `Price`, `Quantity`, `Currency`, Lagerplatz`)'+
              'VALUES (:ArtikelID, :ManufacturerName, :ManufacturerPN, :Supplier, :SupplierPN, :Description, '+
              ':PhotoURL, :Price, :Quantity, :Currency, :Lagerplatz)';
AdoQueryMSSql.Open;
while not AdoQueryMSSql.Eof do
begin
  for i := 0 to AdoQueryMSSql.FieldCount - 1 do
    AdoQueryMySql.Parameters[i].Value := AdoQueryMSSql.Fields[i].AsVariant;
  AdoQueryMySql.ExecSQL;
  AdoQueryMSSql.Next;
end;



Все. Если заменить оба ADOQuery на ADOCommand будет быстрее
...
Рейтинг: 0 / 0
19.07.2018, 17:20
    #39676372
user00001
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отправить много данных в MySQL одним потоком
что-то я не так делаю.
То что вы дали я встроил вместо того запроса и теперь ничего в программе не выполняется и возвращается
"Argument out of range"
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отправить много данных в MySQL одним потоком / 25 сообщений из 49, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]