|
Некоторое время назад мне нужно было решить задачу по настройке репликации транзакцией БД под 1С из одного сервера на другой, при реализации я столкнулся со следующей проблемой. В основном, проблему можно сформулировать так, что при изменении структуры БД мастер репликации требует переформирования всей схемы БД, а не конкретно выбранного объекта. Также поставленные на репликацию таблицы нельзя никаким переименовывать, удалять, что 1С и делает при изменении структуры БД. То есть, конечно, можно было перед изменением структуры снимать все (можно конечно только измененные, но их нужно знать заранее) таблицы с репликации, а затем ставить заново, но эта операция требует гораздо большего времени (и сетевого трафика), чем изменение настройки репликации конкретного объекта.
Нужно было решить следующие проблемы:
1) Возможность изменения структуры реплицируемых объектов 2) Возможность определения измененных объектов до начала изменения структуры конфигурации 1С и после. 3) Изменение настройки правил репликации только для измененных объектов. 4) На издателе формировался триггер for update в котором не использовалась конструкция set nocount on.
Первая проблема решалась изменением служебных полей определяющих статус реплицируемой таблицы в sysobjects.
Вторая проблема решалась сохранением слепка sysobjects до изменений и сравнение его с sysobjects после изменений.
drop table copysysobjects select * into copysysobjects from sysobjects where xtype='U' and status>0
--сохранение слепка до изменений
select id,name from sysobjects cso where cso.id not in (select id from copysysobjects) and xtype='U' and status>0
--определение измененных объектов
Третья проблема решалась с помощью использования хранимых процедур sp_dropsubscription, sp_droparticle,
для снятия объектов, определенными предыдущим скриптом, с репликации(с подписки и издателя соответственно). А также с помощью sp_addarticle, sp_addsubscription соответственно для постановки на репликацию. Нужно отметить также, что для
больших таблиц можно было бы пользоваться хранимыми процедурами по постановке не таблицы целиком на репликацию а только колонки.
Четвертая проблему можно решать несколькими способами. Один из них это изменение шаблона репликационного триггера. Второй это изменение триггеров дополнительным скриптом.(Хотя первый способ мне кажется более красивым и надежным)
declare @str char(8000) declare @dropstr char(8000) declare @trigger_name char(100)
declare Mylog cursor local fast_forward for select rtrim(c.text),rtrim(o.name) from dbo.syscomments c, dbo.sysobjects o where o.id = c.id and o.name like '%sp_MSsync_upd_trig_%' order by c.number, c.colid open Mylog fetch Mylog into @str,@trigger_name while (@@fetch_status<>-1) begin set @dropstr='drop trigger '+rtrim(@trigger_name) set @str=rtrim(replace(@str,' declare @rc int',' declare @rc int set nocount on')) set @str=rtrim(@str)+'set nocount off' select @str exec(@dropstr) exec(@str) fetch Mylog into @str,@trigger_name end close Mylog deallocate Mylog
P.S. У автора статьи на базе репликации транзакцией для 1С есть уже готовое, прошедшее внедрения, решение.
Для описанной выше задачи оказалось более эффективным решение не предполагающее изменение в структуре БД 1С. То есть измененный мастер репликации MSSQL вообще не вносит никаких изменений в структуру существующих таблиц.
Обсуждение статьи
Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").
|