powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отправить много данных в MySQL одним потоком
25 сообщений из 49, страница 1 из 2
Отправить много данных в MySQL одним потоком
    #39676183
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пытаюсь в 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
Отправить много данных в MySQL одним потоком
    #39676194
чччД__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
user00001,

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

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

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

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676219
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 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
Отправить много данных в MySQL одним потоком
    #39676225
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Отправить много данных в MySQL одним потоком
    #39676232
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 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
Отправить много данных в MySQL одним потоком
    #39676248
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user00001
Код: html
1.
Too many connections


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

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


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

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

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

Ну и как wadman предлагал одним скриптом по тысяче записей тоже нормальная альтернатива транзакции.
Причём 1000 - это условное число - им можно поиграться в сторону уменьшения / увеличения.
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676294
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Отправить много данных в MySQL одним потоком
    #39676295
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanНе совсем. В моем примере мускульный вариант вставки сразу трех строк, а не одной. Можно и 100 строк одним махом вставить. Мне тут один бэкап попался Postgresql, так там оказывается в порядке вещей в SQL после INSERT CSV фигачить. За один INSERT можно легко сотню-другую тысяч записей вставить. Буквально за секунду. :D
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676309
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята,

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

Код: 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
Отправить много данных в MySQL одним потоком
    #39676320
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можете видеть, как я сделал не очень хороший цикл и создаю убогим методом запрос-строку...
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676325
Tactical Nuclear Penguin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user00001Можете видеть, как я сделал не очень хороший цикл и создаю убогим методом запрос-строку...

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



Смотрите на закомментированные строки слэшами //, это были мои варианты
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676333
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, чтобы не разбираться в моём бреде, напишите свой вариант, потому что я точно что-то напутал
...
Рейтинг: 0 / 0
Отправить много данных в MySQL одним потоком
    #39676337
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Отправить много данных в MySQL одним потоком
    #39676341
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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
Отправить много данных в MySQL одним потоком
    #39676372
user00001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что-то я не так делаю.
То что вы дали я встроил вместо того запроса и теперь ничего в программе не выполняется и возвращается
"Argument out of range"
...
Рейтинг: 0 / 0
25 сообщений из 49, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отправить много данных в MySQL одним потоком
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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