|
Как из 1с8 в MySQL записывать сразу групу строк из ТЗ (ну или сразу всю ТЗ)? | ☑ | ||
---|---|---|---|---|
0
MikhaDi4
26.03.13
✎
19:54
|
Привет!
Подскажите, кто знает, как сабж сделать? SQL синтаксис почти не знаю. Из 1с8 подключаюсь через ОДБЦ к базе MySQL и требуется обновлять одну из табличек этой БД. Прочитал немного по sql, мне вроде подходит оператор MERGE, но до его использования я пока не дошел. Смотрю сначала, как табличку хотябы просто заполнить. Есть оператор insert (ТекстЗапроса = "INSERT INTO `itemsinfo` (id, NAME, value) VALUES (4, ""Леопольд"", 1200)"), он работает, но это получается, что если у меня тысяча строк в 1С, то нужно последовательно тысячу раз сделать такой запрос... Понятно, что чтучки вроде передачи такого запроса : ТекстЗапроса = "INSERT INTO `parser_itemsinfo` SELECT * FROM "+ТЗ; (где ТЗ моя табличка, пусть и с такимиже названиями колонок) выдает ошибку. Вот хочу узнать, может кто знает, как записать в скуль сразу всю табличку из 1С, ну и вообще как лучше внешние sql таблицы обновлять, каким оператором и т.п.? |
|||
1
Fragster
гуру
26.03.13
✎
19:57
|
||||
2
Kreont
26.03.13
✎
19:58
|
я за "insert" :)
Главное учти что есть ограничение на к-во текста в одном запросе, так "на глаз" то всегда делю по макс 1000 строк в один запрос вставки. |
|||
3
Живой Ископаемый
26.03.13
✎
19:59
|
а что уже нет никаких bulkisert'ов?
|
|||
4
Diversus
26.03.13
✎
20:00
|
внНаборЗаписейИзменений = Новый COMОбъект("ADODB.RecordSet");
внНаборЗаписейИзменений.CursorLocation = 2; внНаборЗаписейИзменений.LockType = 3; внНаборЗаписейИзменений.Open("journ_rec", внСоединение); Для Каждого Строки Из ИзмененияТЧ Цикл внНаборЗаписейИзменений.AddNew(); внНаборЗаписейИзменений.Fields("journ_uid").Value = ИДЗаписиВЖурнале; Если НЕ ПустаяСтрока(Строки.ИмяТЧ) Тогда внНаборЗаписейИзменений.Fields("nametp").Value = Строки.ИмяТЧ; внНаборЗаписейИзменений.Fields("numtp").Value = Строки.НомерСтрокиТЧ; КонецЕсли; внНаборЗаписейИзменений.Fields("namerec").Value = Строки.ИмяРеквизита; внНаборЗаписейИзменений.Fields("typerec").Value = Строки.ТипРеквизита; Если НЕ ПустаяСтрока(Строки.НовоеПредставление) Тогда внНаборЗаписейИзменений.Fields("newview").Value = Строки.НовоеПредставление; КонецЕсли; Если НЕ ПустаяСтрока(Строки.НовоеЗначение) Тогда внНаборЗаписейИзменений.Fields("newval").Value = Строки.НовоеЗначение; КонецЕсли; внНаборЗаписейИзменений.Update(); КонецЦикла; внНаборЗаписейИзменений.Close(); |
|||
5
MikhaDi4
26.03.13
✎
20:01
|
(2) угу, я тоже подумал, что если шибко дофига строк в таблице, то это может плохо кончиться, нужно типа порциями сувать. Но хз как
|
|||
6
MikhaDi4
26.03.13
✎
20:03
|
(3) я BULK INSERT смотрел, но там вроде файл надо дать скулю. Это не подходит по моему.
|
|||
7
MikhaDi4
26.03.13
✎
20:08
|
(1) очень не привычно ))) а есть прмер использования на 1с написанный?
|
|||
8
Живой Ископаемый
26.03.13
✎
20:10
|
2(6) почему? тяжело записать тз в файл? или она того не стоит? :)
|
|||
9
Fragster
гуру
26.03.13
✎
20:11
|
(8) проблема, наверное, этот файл мускулю просунуть в доступ
|
|||
10
MikhaDi4
26.03.13
✎
20:19
|
(8) ха ха, ну не, не проблема конечно )) Но, есть ограничения в правах на сервере mysql и он далеко находится (и мне кажется неочень хорошо будет здоровый файл гонять, хотя посмотрю конечно), кроме того, мы хотим уйти от обмена через файл... (сейчас 1с выплевывает файлик, который читается левой программкой и пишется в мускуль).
|
|||
11
Александр_
Тверь 26.03.13
✎
20:21
|
можешь воспользоваться готовой компонентой и не сильно переживать.
http://infostart.ru/public/165027/ |
|||
12
Живой Ископаемый
26.03.13
✎
20:23
|
(10) поставь мс скл на сервере 1с, чтобы утилита балкинсерт была бы тут, рядом. Файл нужно подсовывать этой утилите а не мссклю, а она уже может булкать в удаленный мсскл сервер. Ничем от адодб это отличаться не будет.
|
|||
13
Fragster
гуру
26.03.13
✎
20:24
|
(12) май эс ку эль
|
|||
14
Живой Ископаемый
26.03.13
✎
20:24
|
Блин, майскл а не мсскл. Тогда не знаю
|
|||
15
Александр_
Тверь 26.03.13
✎
20:28
|
вообще, одним запросом это делается примерно так:
INSERT INTO `itemsinfo` (id, NAME, value) VALUES (4, "Леопольд", 1200), (10, "Он", 1300), .... (10, "Он", 1400) и т.д. обработка из (11) умеет все что нужно делать. Пользоваться очень легко. Сама разбивает большие таблицы на порции по 1000 строк (по опыту - оптимальный размер, но параметр можно изменить). Можно просто как образец посмотреть. Обработка моя и если нет доступа на инфостарт могу прислать на e-mail. |
|||
16
Fragster
гуру
26.03.13
✎
20:31
|
(15) на самом деле надо рубить по max_allowed_packet
|
|||
17
Александр_
Тверь 26.03.13
✎
20:32
|
(16) не факт. разрешенным может быть очень большое количество, но вот тупо зависает.
я отправлял таблицу в 10 000 строк - проходило, но медленные чем 10 по 1000. |
|||
18
Александр_
Тверь 26.03.13
✎
20:33
|
кстати, обработка если не получилось с первого раза - делает три попытки передать текущую порцию. если все попытки провалились только тогда прекращает работу и возвращает ошибку.
|
|||
19
Александр_
Тверь 26.03.13
✎
20:33
|
количество попыток - так же настраивается.
|
|||
20
MikhaDi4
26.03.13
✎
20:37
|
(15) ну я и имел в виду такой запрос (по ошибке про цикл написал).
(15) Доступ есть, к сожалению, только на работе к ИС. Можешь выслать на электронку (mr.samuelsonГАВГАВya.ru)? |
|||
21
Александр_
Тверь 26.03.13
✎
20:39
|
(20) ты собираешь запрос вида
INSERT INTO `itemsinfo` (id, NAME, value) VALUES (4, "Леопольд", 1200), (10, "Он", 1300) с нужным количеством строк - и отправляешь один раз. а не по одной строке INSERT INTO `itemsinfo` (id, NAME, value) VALUES (4, "Леопольд", 1200) сейчас вышлю. |
|||
22
MikhaDi4
26.03.13
✎
20:39
|
(4) Списибо.
|
|||
23
MikhaDi4
26.03.13
✎
20:40
|
(21) Спасибо
|
|||
24
Александр_
Тверь 26.03.13
✎
20:43
|
(23) отправил.
обработка не очень сложная, но перекрывает практически все потребности по работе с MySQL в части касающейся отправки и приема данных. У меня оно в боевом режиме каждый день используется для обмена с кассовым ПО. |
|||
25
MikhaDi4
26.03.13
✎
20:43
|
(21) дык этот один запрос (большой) и вызвал у меня сомнения. Его веть на порции делить нужно. А между порциями переданных запросов на скуль, данные в самом скуле, гипотетически, могут измениться.. Обраотку получил.
|
|||
26
Александр_
Тверь 26.03.13
✎
20:45
|
(25) а как ты хочешь передавать данные не перечисляя их все?
А то, что их их делить надо - это факт. |
|||
27
MikhaDi4
26.03.13
✎
20:47
|
(26) я не знаю. Думал, что ну, что-то типа контейнера на скуле сделать, заполнить его. А потом таблицу залочить для изменеия кем либо кроме меня и обновить... Но, может это и баловство.
|
|||
28
MikhaDi4
26.03.13
✎
20:47
|
ах да, я не владею терминологией скуля )))
|
|||
29
Александр_
Тверь 26.03.13
✎
20:48
|
(27) все зависит от того какие задачи решаются.
Но лично мне таким заниматься не приходилось. Ибо просто не нужно. |
|||
30
MikhaDi4
26.03.13
✎
20:50
|
(26) так у тебя ф-я ОтправитьДанныеПоПодготовленнойТаблице именно то, что в (21) и делает так?
|
|||
31
Александр_
Тверь 26.03.13
✎
20:51
|
(30) да.
правда еще при этом разбивает таблицу на нужное количество строк + при в случае неудачной отправки данных делает 3 попытки их отправить. |
|||
32
MikhaDi4
26.03.13
✎
20:52
|
(31) угу. Спасибо, хорошая обработка.
|
|||
33
Александр_
Тверь 26.03.13
✎
20:53
|
блин... забыл версию обработки обновить на инфостарте :)
у меня есть еще функция ОтправитьДанныеПоСтруктуре т.е. кидаешь структуру в которой ключ имя таблицы, а значение - таблица. и оно все само отправляет. завтра обновлю. |
|||
34
Александр_
Тверь 26.03.13
✎
20:53
|
это если сразу кучу таблиц надо отправить
|
|||
35
Александр_
Тверь 26.03.13
✎
20:54
|
+ доделал возможность игнорирования вставки дубликатов.
Если отправляемая таблица содержит дубли с тем, что уже есть в таблице на MySQL. |
|||
36
MikhaDi4
26.03.13
✎
20:55
|
а как-то типа оператора Merge нельзя сделать?
|
|||
37
MikhaDi4
26.03.13
✎
20:57
|
А проверка этих дублей идет по всем полям или список таких (ключевых)полей можно задать?
|
|||
38
ksergey
26.03.13
✎
21:04
|
(21) Уважаемый, подскажи, есть ли вариант "пакетного" запроса для команды
UPDATE table SET field1 = ****, field2 = **** WHERE id=xxxxxxx Спасибо |
|||
39
Александр_
Тверь 26.03.13
✎
21:06
|
(38) а что значит "пакетного"?
сразу кучу запросов через точку с запятой? |
|||
40
Александр_
Тверь 26.03.13
✎
21:07
|
(37) по ключевым полям. это из области синтаксиса MySQL
|
|||
41
ksergey
26.03.13
✎
21:07
|
(39) наверно типа такого - это же всё одно будет быстрей чем 1000 раз гнать пакеты по одной команде
|
|||
42
Александр_
Тверь 26.03.13
✎
21:09
|
(41) нет, такой возможности, на сколько мне известно -нет.
Правда обработка из (11) эмулирует пакетную работу. т.е. в нее можно передать один большой запрос разделенный точкой с запятой, а обработка сама его разобьет на отдельные запросы. Вообще не вижу проблемы, если соединение держать открытым (а не каждый раз зыкрывать), то больших проблем не будет. Так же, если нужно ну очень много данных проапдейтить, может проще их удалить (перечислить все id) и залить заново одной командой? |
|||
43
Александр_
Тверь 26.03.13
✎
21:11
|
т.е. первый запрос типа delete - удаляет 1000 записей, которые ты хочешь обновить
второй запрос - один instrt на 1000 строк. Правда не уверен, что это будет быстрее чем 1000 раз Update сделать. надо тестить (возможно на разных данных будет разный результат). |
|||
44
ksergey
26.03.13
✎
21:19
|
(43) понятно.
спасибо за обстоятельный ответ |
|||
45
ksergey
26.03.13
✎
21:32
|
(42) недавно нечто подобное делал для базы сайта на MSSQL.
Подход с массой вставкой был реализован по схожей схеме: INSERT INTO dbo.Owner (field1,field2,field3) SELECT value1,value2,value3 UNION ALL SELECT value11,value12,value13 UNION ALL SELECT value21,value22,value23 ... так скорость выросла примерно в 2,5 раза по сравнению если вставлять одиночными пакетами |
|||
46
Александр_
Тверь 26.03.13
✎
21:44
|
(45) думаю очень много зависит от самого характера данных.
но я не решал задачу оптимизацию обновления большого массива данных, по этому опыта в данном вопросе - нет. |
|||
47
Александр_
Тверь 27.03.13
✎
08:26
|
(37) если интересно, то обновил (11) до последней версии.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |