Вернуться к статье

Листинг 1. Для подготовки центральной БД к работе в распределенной среде нужно сделать следующее

  1. Применить поля с типом ROWGUIDCOL в качестве первичных ключей. (У поля ROWGUIDCOL должен быть еще признак ISROWGUID - Прим. ред.).
  2. Сформировать все таблицы так, чтобы эти поля с первичными ключами были самыми последними, например:
    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())
    )
  3. Для первичных ключей таблиц добавить атрибут NONCLUSTERED:
    ALTER TABLE Sheriff
           ADD PRIMARY KEY NONCLUSTERED
     (SheID)
  4. Указать, что вся ссылочная целостность не должна учитываться в процессе тиражирования:
    ALTER TABLE Sheriff
         ADD FOREIGN KEY (DivID)
                    REFERENCES Division NOT FOR
     REPLICATION
  5. Для всех таблиц, содержащих вторичные ключи, для предотвращения конфликтов при тиражировании полей определяющих ссылочную целостность, добавить следующие триггеры:
    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


Вернуться к статье