| 
    
            
         
         | 
    
  | 
Как из 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) до последней версии.     
         | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |