Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм (число прочтений - 6995 )
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
29. Мая 2009 :: 06:30
Печать  
Задача следующая: две базы 1С. нужно, в одной базе, затягивать прямыми запросами справочники из другой базы, и их синхронизировать. для 1-го уровня все просто. НО, для многоуровнего справочника, я не могу определиться с алгоритмом, по которому это делать. Получается аж три прохода, что долго. Далаю так:
- Запросом, получаю ТЗ с данными справочника
- перебераю элементы ТЗ, нахожу в текущем справ.по коду, обновляю элемент/группу, причем все помещаю в корень (на данном этапе может и не быть родительской группы)
- После того как все обновленно, переберая справочник, устанавливаю иерархию (проход 2)
- а теперь нужно снова пробежаться по справочнику, и удалить элементы, которых нет в пришедшем наборе записей.

Получается, что справочник трижды переберается "с записью".
Долго, даже в транзакции.
Может быть у уважаемого сообщества есть мысли как оптимизировать сей алгоритм?
  
Наверх
 
IP записан
 
U_zer
Экс-Участник


Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #1 - 29. Мая 2009 :: 06:51
Печать  
w202 писал(а) 29. Мая 2009 :: 06:30:
Задача следующая: две базы 1С. нужно, в одной базе, затягивать прямыми запросами справочники из другой базы, и их синхронизировать. для 1-го уровня все просто. НО, для многоуровнего справочника, я не могу определиться с алгоритмом, по которому это делать. Получается аж три прохода, что долго. Далаю так:
- Запросом, получаю ТЗ с данными справочника
- перебераю элементы ТЗ, нахожу в текущем справ.по коду, обновляю элемент/группу, причем все помещаю в корень (на данном этапе может и не быть родительской группы)
- После того как все обновленно, переберая справочник, устанавливаю иерархию (проход 2)
- а теперь нужно снова пробежаться по справочнику, и удалить элементы, которых нет в пришедшем наборе записей.

Получается, что справочник трижды переберается "с записью".
Долго, даже в транзакции.
Может быть у уважаемого сообщества есть мысли как оптимизировать сей алгоритм?

Введи реквизит - полный код в справочнике, пропиши его.
Далее, после получения выборки - сразу синхронизируй по полному коду. Если элемент найден - обновляй, нет - запускай процедурку разбора полного кода. Получается всего один проход.
  
Наверх
 
IP записан
 
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #2 - 29. Мая 2009 :: 07:06
Печать  
Цитата:
w202 писал(а) 29. Мая 2009 :: 06:30:
Задача следующая: две базы 1С. нужно, в одной базе, затягивать прямыми запросами справочники из другой базы, и их синхронизировать. для 1-го уровня все просто. НО, для многоуровнего справочника, я не могу определиться с алгоритмом, по которому это делать. Получается аж три прохода, что долго. Далаю так:
- Запросом, получаю ТЗ с данными справочника
- перебераю элементы ТЗ, нахожу в текущем справ.по коду, обновляю элемент/группу, причем все помещаю в корень (на данном этапе может и не быть родительской группы)
- После того как все обновленно, переберая справочник, устанавливаю иерархию (проход 2)
- а теперь нужно снова пробежаться по справочнику, и удалить элементы, которых нет в пришедшем наборе записей.

Получается, что справочник трижды переберается "с записью".
Долго, даже в транзакции.
Может быть у уважаемого сообщества есть мысли как оптимизировать сей алгоритм?

Введи реквизит - полный код в справочнике, пропиши его.
Далее, после получения выборки - сразу синхронизируй по полному коду. Если элемент найден - обновляй, нет - запускай процедурку разбора полного кода. Получается всего один проход.


Исходную (ту из которой тяну) конфу менять нельзя, к сожалению. Хотя все равно не понял предложения. Ну получил я элемент с полным кодом, допустим он найден в тек.справочнике, и что? как я его могу обновить, ведь нет уверенности, что его родительская группа уже загруженна. И еще.. могут быть чудесные ситуации, когда по коду найден элемент, а в исходном наборе записей - это группа (так быть может..)
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #3 - 29. Мая 2009 :: 07:18
Печать  
(0) 1.База УРБД или нет ?
2. В ту базу куда перебрасываешь могут ли быть еще другие элементы справочников ?
  
Наверх
 
IP записан
 
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #4 - 29. Мая 2009 :: 07:23
Печать  
Z1 писал(а) 29. Мая 2009 :: 07:18:
(0) 1.База УРБД или нет ?
2. В ту базу куда перебрасываешь могут ли быть еще другие элементы справочников ?

Нет, база НЕ урбд, "посторонних" элементов быть не может, НО, у синхронизируемых элементов в текущей базе есть реквизиты, которых нет в удаленной базе, и они нужны
  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #5 - 29. Мая 2009 :: 07:24
Печать  
Если база Sql-ная то записывай средствами SQL  INSERT, UPDATE,
а синхронизацию делай по Id, ParentId, IsFolder
База источник(Id, ParentId, IsFolder) = База преемник(Id, ParentId, IsFolder)
  
Наверх
 
IP записан
 
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #6 - 29. Мая 2009 :: 07:24
Печать  
а действительно, механизм УРБД в этом случае по какому алгоритму работает?
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #7 - 29. Мая 2009 :: 07:26
Печать  
w202 писал(а) 29. Мая 2009 :: 07:23:
Z1 писал(а) 29. Мая 2009 :: 07:18:
(0) 1.База УРБД или нет ?
2. В ту базу куда перебрасываешь могут ли быть еще другие элементы справочников ?

Нет, база НЕ урбд, "посторонних" элементов быть не может, НО, у синхронизируемых элементов в текущей базе есть реквизиты, которых нет в удаленной базе, и они нужны

тогда просто создваешь элементы с теми же id  и
РодительId  ВладелецID

Но учти что при переносе за тобой стоит отработка еще всяких отборов.
  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #8 - 29. Мая 2009 :: 07:27
Печать  
Если базы разные (Отличаются хотябы одним реквизитом) УРБД не подойдет.
  
Наверх
 
IP записан
 
ol
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 272
Местоположение: Санкт-Петербург
Зарегистрирован: 24. Января 2009
Пол: Мужской
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #9 - 29. Мая 2009 :: 07:49
Печать  
а что мешает сразу сделать иерархический запрос к источнику ? и потом в последовательности иерархии создавать вначале группы, потом элементы. Такой ситуации, что родительской группы нет здесь не возникнет
  
Наверх
ICQ  
IP записан
 
Alex_Bob
Full Member
***
Отсутствует



Сообщений: 136
Местоположение: Липецк
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #10 - 29. Мая 2009 :: 07:51
Печать  
Тогда в справочнике базы приемника заведи 2 реквизита myID и myVerstamp

Код следующих трех примеров предельно упрощен

Для получения списка ID добавленных записей:
Код
Выбрать все
SELECT l.ID FROM ТаблицаИсточник AS l
LEFT JOIN ТаблицаПриемник AS r
ON l.ID=r.myID
WHERE ISNULL(r.myID)
 



Для получения списка ID удаленных записей:
Код
Выбрать все
SELECT l.myID FROM ТаблицаПриемник AS l
LEFT JOIN ТаблицаИсточник AS r
ON l.myID=r.ID
WHERE ISNULL(r.ID)
 




Для получения списка ID измененных записей:
Код
Выбрать все
SELECT l.ID FROM ТаблицаИсточник AS l, ТаблицаПриемник AS r
WHERE  (l.ID=r.myID) AND (l.Verstamp>r.myVerStamp)
 



Для сведения: таблицы справочников и журнал имеют поле Verstamp, значение которого увеличивается на 1 при каждом изменении.
При каждом сеансе синхронизации надо заполнять и эти поля. Так как полученные списки элементов гораздо короче, процедура синхронизации выполняется быстро.

Я подобным алгоритмом пользуюсь уже давно
  

Необходимо время, чтобы восстановить хаос. (с) Дж. Буш (младший)
Наверх
 
IP записан
 
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #11 - 29. Мая 2009 :: 11:32
Печать  
Alex_Bob писал(а) 29. Мая 2009 :: 07:51:
Тогда в справочнике базы приемника заведи 2 реквизита myID и myVerstamp

Код следующих трех примеров предельно упрощен

Для получения списка ID добавленных записей:
Код
Выбрать все
SELECT l.ID FROM ТаблицаИсточник AS l
LEFT JOIN ТаблицаПриемник AS r
ON l.ID=r.myID
WHERE ISNULL(r.myID)
 


...
Я подобным алгоритмом пользуюсь уже давно


я недавно начал разбираться с 1с++ так что вопрос сразу в лоб))
Разве возможно в одном запросе подцепить 2 базы?

Если возможно, то порядок очевидно такой:
- Получаю ТЗ добавленны в Родительской базе элементов(групп), далее, средствами 1с добавляю их
- Получаю табл. измененных, удаленных, аналогично отрабатываю

На первый взгляд при таком подходе коллизий быть не может, т.е. все очень быстро, и очень правильно)))
  
Наверх
 
IP записан
 
w202
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 18
Зарегистрирован: 28. Мая 2009
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #12 - 29. Мая 2009 :: 12:16
Печать  
ol писал(а) 29. Мая 2009 :: 07:49:
а что мешает сразу сделать иерархический запрос к источнику ? и потом в последовательности иерархии создавать вначале группы, потом элементы. Такой ситуации, что родительской группы нет здесь не возникнет

к своему стыду, я пока не знаю, как средставми SQL, сделать иерархический запрос Озадачен
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #13 - 29. Мая 2009 :: 13:19
Печать  
может чего-то не понял, но зачем тут иерархические запросы?
Если базы на одном сервере и справочники не очень большие, то собсно достаточно 2х запросов.
Это при условии, что ID совпадают. Если не совпадают, можно завести на справочнике-приемнике реквизит "IDИсточника"(правда придется при вставке новых новый ид генерировать)
Код
Выбрать все
--обновляем существующие
update [БазаПриемник]..[scXXX]
 set
  parentid = scИсточник.parentid,
  isfolder = scИсточник.isfolder,
  ismark   = scИсточник.ismark,
  spXX01   = scИсточник.spYY01
  /*перечисляем все колонки scИсточник, и значения по умолчанию для колонок приемника*/
from
 [БазаПриемник]..[scXXX] scПриемник
inner join
 [БазаИсточник]..[scYYY] scИсточник on scИсточник.id = scПриемник.id 


Код
Выбрать все
 --доавляем новые
insert into [БазаПриемник]..[scXXX](/*список колонок*/)
select
  id       id,
  parentid parentid,
  isfolder isfolder,
  ismark   ismark,
  spXX01   spYY01
  /*перечисляем все колонки scИсточник, и значения по умолчанию для колонок приемника*/
from
 [БазаИсточник]..[scYYY] scИсточник
where
 not exists(select * from [БазаПриемник]..[scXXX] scПриемник where scПриемник.id = scИсточник.id) 



  
Наверх
 
IP записан
 
ol
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 272
Местоположение: Санкт-Петербург
Зарегистрирован: 24. Января 2009
Пол: Мужской
Re: офф/2 Синхронизация многоуровнего справочника. Предлагаю обсудить алгоритм
Ответ #14 - 29. Мая 2009 :: 16:45
Печать  
иерархический запрос в принципе возможен
что то вроде left join (тот же справочник) on (условие на parentid)

- но я имел в виду возможности Индексированной таблицы - не уточнил - извиняюсь.
Есть такой метод у нее Группировать()

все таки, добавлять новые записи лучше штатным механизмом; меньше возни с несколькими нюансами, которые обязательно возникнут, если писать в таблицу напрямую. Если, конечно, объемы совсем уж критические, то  есть смысл и повозиться с нюансами
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать