Вернуться к статье
Листинг 1. Для подготовки центральной БД к работе в распределенной среде нужно сделать следующее
- Применить поля с типом ROWGUIDCOL в качестве первичных ключей. (У поля ROWGUIDCOL должен быть еще признак ISROWGUID - Прим. ред.).
- Сформировать все таблицы так, чтобы эти поля с первичными ключами были самыми последними, например:
exec sp_addtype SSP_ID, «uniqueidentifier», «NULL» exec sp_addtype SPP_LOGIC, «bit», «NULL» exec sp_addtype SSP_NAME, «varchar(255)», «NULL» CREATE TABLE Sheriff ( DivID SSP_ID, SheNAME SSP_NAME NOT NULL, SheRIGHT SPP_LOGIC, SheID SSP_ID ROWGUIDCOL NOT NULL DEFAULT (newid()) )
- Для первичных ключей таблиц добавить атрибут NONCLUSTERED:
ALTER TABLE Sheriff ADD PRIMARY KEY NONCLUSTERED (SheID)
- Указать, что вся ссылочная целостность не должна учитываться в процессе тиражирования:
ALTER TABLE Sheriff ADD FOREIGN KEY (DivID) REFERENCES Division NOT FOR REPLICATION
- Для всех таблиц, содержащих вторичные ключи, для предотвращения конфликтов при тиражировании полей определяющих ссылочную целостность, добавить следующие триггеры:
CREATE TRIGGER SheriffNULL ON Sheriff FOR INSERT, UPDATE AS If UpDate(DivID) If Not Exists (Select * From Division Where Division.DivID in (Select DivID From inserted)) Update Sheriff Set DivID = NULL
Не все таблицы базы данных могут содержать вторичные ключи с атрибутом NULL. В таком случае перечисленные триггеры, которые обеспечивают единство подхода к предотвращению конфликтов, не будут возвращать значения.
Листинг 2. Участок sp_MSadd_merge_anonymous_agent, требующий исправления
… begin select @subid = anonymous_subid from MSmerge_agents where publisher_id=@publisher_id and publisher_db = @publisher_db and publication = @publication and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db …
Вернуться к статье
Листинг 3. Участок sp_MSadd_merge_anonymous_agent с внесенным исправлением
… begin select @subid = anonymous_subid from MSmerge_agents where publisher_id=@publisher_id and publisher_db = @publisher_db and publication = @publication and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db and subscriber_name = @subscriber_name …
Вернуться к статье
Листинг 4. Основные части клиентской программы (Visual Basic 6.0).
… Set sm = New SQLMerge Set sre = New SQLReplError ? Определить необходимые свойства репликационного процесса sm.Publisher = «SERVER» sm.PublisherDatabase = «MyBaseMERGE» sm.Publication = «ForAccess» sm.PublisherLogin = GetRightString(cLoginAccess) sm.PublisherPassword = GetRightString(cPasswordAccess) sm.Subscriber = CompName() ? Получить конкретное имя компьютера sm.SubscriberDatasourceType = JET4_DATABASE sm.SubscriberDatabasePath = «custombase.mdb» sm.SubscriberLogin = GetRightString(cLoginAccess) sm.SubscriberPassword = GetRightString(cPasswordAccess) sm.LoginTimeout = 60 sm.QueryTimeout = 600 If KeyInit Then ? Если необходимо повторное создание базы sm.ReinitializeSubscription End If On Error GoTo Failure sm.Initialize sm.Run sm.Terminate ? Установить необходимые права на таблицы SetRights Failure: For Each sre In sm.ErrorRecords MsgBox sre.Description, vbOKOnly, « Ошибка репликации : « + CStr(sre.ErrorNumber) Next Set sm = Nothing Set sre = Nothing … … Declare Function GetComputerName Lib «kernel32» Alias «GetComputerNameA» (ByVal lpBuffer As String, nSize As Long) As Long … ? Получить имя компьютера Public Function CompName() As String Dim Comp As String * 100 Dim rs As Long CompName = «» rs = GetComputerName(Comp, Len(Comp)) If rs <> 0 Then CompName = Comp End Function … … ? Декодировать строку Private Function GetRightString(tmpString As String) As String Dim rc As String, i As Long, tmpChr As String For i = 1 To Len(tmpString) tmpChr = Chr(Asc(Mid(tmpString, i, 1)) - &H55) rc = rc + tmpChr Next GetRightString = rc End Function ? Установить необходимые права на таблицы Private Sub SetRights() Dim dbs As Database Dim ctr As Container Dim doc As Document Dim i As Long Dim strNames As String strNames = «Appeal» & «,» & «Sender» & «,» & «SheApp» & «,» & «ObjApp» & «,» & «Source» & «,» _ & «Document» & «,» & «LogAcc» & «,» & «History» & «,» & «Execution» & «,» & «Assets» & «,» _ & «Object» & «,» & «ObjDoc» & «,» & «Action» & «,» & «Charge» & «,» & «Penalty» & «,» _ & «Tender» & «,» & «Name» & «,» & «Measure» DBEngine.SystemDB = «system.mdb» DBEngine.DefaultUser = GetRightString(cLoginAccess) DBEngine.DefaultPassword = GetRightString(cPasswordAccess) Set dbs = OpenDatabase(«custombase.mdb») Set ctr = dbs.Containers(«Tables») For i = 0 To ctr.Documents.Count - 1 Set doc = ctr.Documents(i) If doc.Owner = GetRightString(cLoginAccess) Then doc.UserName = «Users» If InStr(strNames, doc.Name) <> 0 Then If doc.Name = «Name» Or doc.Name = «Measure» Then doc.Permissions = dbSecRetrieveData Or dbSecInsertData Else doc.Permissions = dbSecRetrieveData Or dbSecReplaceData Or dbSecInsertData Or dbSecDeleteData End If Else doc.Permissions = dbSecRetrieveData End If End If Set doc = Nothing Next Set ctr = Nothing dbs.Close Set dbs = Nothing End Sub
Вернуться к статье