邪恶八进制信息安全团队技术讨论组's Archiver

EvilOctal 2004-11-25 19:00

[转载]网络数据库的复制和同步

信息来源:HT2003

数据库复本是复制数据库的技术,利用这种技术,可以是数据库的几个拷贝保持同步。数据库的每个拷贝称为一个复本,并且每个复本都包含一个公共的表、查询、窗体、报表、宏和模块的集合;每个复本还可以包含只在本地计算机上使用的本地对象。

  在多用户环境中,一个数据库可能由多个用户使用。在多用户应用程序中,数据库复本可以改善用户共享数据库的途径。用数据库复本可以重新产生一个数据库,使两个或多个用户同时使用自己的数据库复本。尽管各个复本放置在不同的计算机上,但它们是保持同步的。

  数据库复本及其拓扑结构

  一个数据库的两个或多个以上的复本组成一个复本集,每个复本都是复本集的一部分。在复本集中含有数据库的若干复本和设计原版(Design Master),其中设计原版是唯一能够对数据库进行设计修改的复本。同一个复本集中的复本可以相互交换数据后复制对象的更新,这种交换称为同步。

  1.数据库复本的用途

  按照传统的做法,在多用户数据库应用程序中,通常将表从数据库的其它对象中分离出来,使得数据能够驻留在网络服务器上,而查询、窗体、报表、宏以及模块则驻留在用户的计算机上。当需要检索或更新数据库中的信息时,必须先登录到网络上,然后打开计算机上的数据库,再打开服务器上相应的数据库。如果使用数据库复本技术,则可以建立既包含数据又包含对象的单一数据库。

  在下列情况下,应该使用数据库复本:

  (1)需要在各办公室中共享数据。可以用数据库复本建立一个单位的数据库的拷贝,然后将其发送给每个相关的办公室。用户在每个办公室把数据输入到自己的复本中,并使所有的远程复本都与单位的复本同步。下属的各级复本能够维护本地表,在该表中含有其它复本中的信息。

  (2)需要在分散的用户之间共享数据。各终端用户在办公室以外输入到数据库中的新信息,可以在终端与单位的网络建立起电子连接的任何时候被同步。在日常工作中,终端用户可以拨入网络,使复本同步,使用数据库的当前最新版本。由于在同步期间只传输新增的更改,因此可以便维持数据更新所花费的时间和费用减到最小。此外,也可使用部分复本(partia1 replicas),只同步部分数据。

  (3)需要提高服务器数据的可访问性。如果应用程序不需要立即更新数据,则可以在主服务器上用数据库复本来减少网络加载。而用服务器本身的数据库拷贝来引入第二服务器,则可以改善响应时间。

  (4)需要发布应用程序的更新。复制应用程序时,不仅自动复制表中的数据,还要复制应用程序的对象。如果对数据库的设计作了更改,则Microsoft Jet数据库引擎将在下一次同步期间传输这些更改,不必发布软件的新版本。

  (5)需要防止全部数据遗失。数据库复本发布跨越多个数据库的数据,因此,当原始数据库被破坏时,可以用复本数据库中的某个数据库来恢复数据。

  虽然数据库复本可以解决分布式数据库处理中固有的许多问题,但是在下列情况下,复本仍然达不到理想要求:

  1.)需要更新多个复本中的大量记录。对于那些需要对不同复本中的现存记录进行频繁更新的应用程序,可能会比简单地往数据库中插入新记录的应用程序产生更多的记录冲突。当位于不同地点的用户同时对同一个记录进行修改时,将会发生记录冲突。应用程序的记录冲突越多,需要的处理时间就越多,因为这些冲突只能通过手工解决。

  2.)对数据一致性的要求非常严格。对于诸如资金过户、航班机票的预订以及包裹装运的跟踪之类的事务处理应用程序,要求ffnu时候的信息不能有半点差错。如果能在一个复本内处理事务,就不要在几个复本中处理。在同步期间,各复本间交换的信息,是事务的结果,而不是事务本身。

  2.复本集拓朴结构

  复本集拓扑结构定xT复本集中各复本间的通信以及tonp同步的逻辑。复本集的拓扑结构可以有各种不同的形式,但是对大多数的应用程序来说,较好的拓扑结构有两种,即星型结构和完全连接结构。

  星型拓扑结构有一个集线器(Hub),该集线器定期与每个卫星复本同步。在这种拓扑结构中,所有数据通过单个集中化数据库在各复本之间共享。由于数据在与其它复本同步时至多只需两步“跳跃”,所以星型拓扑结构可以降低数据在各复本中的等待时间。

  在同步期间,如果交换的平均数据量相对较小,则对大多数应用程序来说,星型拓扑结构可能是最有效的解决方案。它的实现相当简单,而且既有效又可靠。如果是第一次实现复本,则最好使用星型拓扑结构。

  如果把星型拓扑结构中的每个复本都变成一个集线器(Hub),就可以变为完全连接的拓扑结构。在完全连接的拓扑结构中,每个复本与复本集中的其它所有复本同步。完全拓扑结构一个最重要的好处是数据传播的等待时间小。因为每个复本与其它所有复本同步,数据可以直接发送给所有复本,而不必经过一系列复本来间接传播。

与复本操作有关的对象、属性和方法

  为了实现复本燥乍, Microsoft Jet数据库引擎提供了多个对象、属性和方法。在这一节中,将介绍与复本操作有关的对象、属性和方法。

  1.Document对象和Documents集合

  Document对象含有关于对象的一个实例的信息,对象可以是一个数据库、表、查询或关系(仅用于Microsoft Jet数据库)。

  每个Container对象有一个包含Document对象的Documents集合(其关系详见VB的帮助文件),这些Document对象描述由Container指定类型的内置对象的实例。表1 列出了Document所描述的对象的类型、其Container对象的名称及Document包含信息的类型。

  Document container 包含的信息

  数据库 数据库 保存的数据库

  表或查询 表或查询 保存的表或查询

  关系 关系 保存的关系

  用Document对象可以实现下列操作:

  ·用Name属性返回由用户或Microsoft Jet数据库引擎在建立对象时给对象所取的名字。

  ·用Container属性返回包含Document对象的Container对象的名称。

  ·用Owner属性设置或返回对象的拥有者。为了设置owner属性,用户必须有对Document对象的写权限,并且必须把userName属性设置为一个现有的user或Group对象的名称。

  ·用UserName属性或Permissions属性设置或返回一个用户或组对象的访问权限。为了设置这些属性,用户必须有对Document对象的写权限,并且必须把userName属性设置为一个现有的User或GrOup对象的名称。

  ·用DateCreated属性和LasUpdated属性分别返回建立Document对象和最后修改Document对象的日期和时间。

  由于一个Document对象对应于一个现有的对象,因此用户不能建立新的Document对象或者删除现有的Document对象。一个Documents集合含有多个Document对象。可以通过以下几种格式引用一个Document对象:

  Documents(0)

  Documents("Name”)

  Documents![name]

  2.container对象和Containers集合

  Contalner对象把相似类型的Document对象放在一个组中。每个Database对象含有由内部container对象组成的Containers集合。应用程序可以定自己的文档类型和相应的容器(仅对Microsoft Jet数据库),但这些对象不一定总是通过DAO支持。某些Container对象由Microsoft Jet数据库引擎定义,也可以由其它应用程序定义。

  Container对象 包含的信息

  数据库 保存的数据库

  表 保存的表及查询

  关系 保存的关系

  说明:

  1.)每个Container对象含有由Document对象组成的Documents集合,通常用Container对象作为到Document对象中信息的直接链接,也可以用container集合为给定类型的Document对象设置安全性。

  2.)用Container对象可以实现以下操作:

  ·用Name属性返回Container对象的预定义名称。

  ·用Permissions和UserName属性来设置container对象的权限;在Container对象的Documents集合中建立Document对象来继承这些访问权限设置。

  ·用owner属性设置或返回Container对象的所有者。为了设置Ower属性,必须写入Container对象的权限,并把属性设置为现有user或Group对象的名称。

  (3)Container对象是由系统预定的,因此不能建立新的container对象,也不能删除现有的Container对象。

  (4)可以通过顺序号或Name属性设置或引用集合中的container对象,例如:

  Containers(0)

  Containers(”name”)

  Containers![Name]

  【例】编写程序,列出Tables容器中的Documents集合。

  在窗体上画一个命令按钮,然后编写如下的事件过程:

  Private Sub Command1_Click()

  Dim dbsnorthwind As Database

  Dim docloop As Document

  Dim prploop As Property

  Set dbsnorthwind = OpenDatabase("e:\f.mdb")

  With dbsnorthwind.Containers!tables

  Debug.Print "documents in " & .Name & "container"

  '列出Table容器中的Documents集合

  For Each docloop In .Documents

  Debug.Print " " & docloop.Name

  Next docloop

  End with

  dbsnorthwind.close

  End sub

该过程列出f.mdb数据库Table容器中的Documents集合。程序运行后,单击命令按钮,即可在“立即”窗口中列出该集合。

3.property对象与Properties集合
  Property对象用来描述一个DAO对象的内部属性或用户定义属性,与DAO对象及Properties集合的关系为DAO对象包含Properties集合,Properties集合包含property对象。(其关系详见VB帮助文件)

  除Connection和Error对象外,每个DAO对象都含有一个property集合,在该集合中有与相应的DAO对象的内部属性一致的Property对象。同时,用户可以定义Property对象并将其加入某些下列DAO对象的Properties集合:

  ·Database, Index, QueryDef和TableDef对象

  ·TableDef对象和QueryDef对象的Fields集合中的Field对象

  Property有4个预定义的属性:

  ·Name属性:是一个字符串,属性的唯一标识。

  ·Type属性:是一个整型数(Integer),用来指定属性的数据类型。

  ·Value属性:是一个包含属性设置的Variant类型的值。

  ·Inherited属性:是一个Boolean值,用来指示属性是否从另一个对象继承而来。

  Property对象既有预定义的属性,也有用户定义的属性,在引用时,其格式是不一样的。顶定义属性的引用格式为:

  对象.属性

  而用户定义的属性必须采用下面的引用格式:

  对象.Properties.(“属性”)

  【例】编写程序,列出Tables容器中的Documents集合,然后列出集合中的第一个Document对象的Properties集合。

  在窗体上画一个命令按钮,然后编写如下事件过程:

  Private Sub Command1_Click()

  Dim dbsnorthwind As Database

  Dim docloop As Document

  Dim prploop As Property

  Set dbsnorthwind = OpenDatabase("e:\f.mdb")

  With dbsnorthwind.Containers!tables

   Debug.Print "documents in " & .Name & "container"

   For Each docloop In .Documents

    Debug.Print " " & docloop.Name

   Next docloop

   With .Documents(0)

    Debug.Print "properties of" & .Name & "document"

    On Error Resume Next

    For Each prploop In .Properties

     Debug.Print " " & prploop.Name & "=" & prploop

    Next prploop

    On Error GoTo 0

   End With

  End With

  dbsnorthwind.Close

  End Sub

程序的前半部分与前面的例子相同,后半部分列出第一个Document对象(即Documents(0) 的 Properties集合。运行程序,单击命令按钮,即可在“立即”窗口中列出上述内容。

  用户定义的属性通过CreateProperty方法来定义,用该方法可以建立由用户定义的Property对象(仅Microsoft Jet 工作区),用于Database,Document,Field,Index,QueryDef和TableDef对象。其格式为:

  set property=对象.CreateProperty(name,type,value,DDL)

  各参数的含义如下:

  ·property:对象变量,要建立的Property对象。

  ·Object:对象变量,可以是Database,Field,Index,QueryDef和TableDef对象,可以对这些对象建立Property对象。

  ·name: 可选。 variant类型(字符串子型),唯一地命名新的Property对象。

  ·type: 可选。 常数,定义新Property对象的类型。

  ·value:可选。 variant类型,指定属性的初值。

  ·DDL: 可选。 Variant类型(Boolean子型),用来指示该属性是否是一个DDl对象,缺省值为False。如果DDL为True,则不能删除这个property 对象(除非得到 dbsecWriteDef的允许)。

  说明:

  1.)只能在一个永久对象的Property集合中建立用户定义的Property对象。在用CreateProperty 方法建立Property对象时,如果省略了一个或多个可选参数,则可在向一个集合追加新的对象之前,用赋值语句设置或重新设置相应的属性。在向集合中追加新的对象之后,可以改变其属性设置的一部分(不是全部)。

  2.)如果name参数指的是该集合中已经存在的对象成员,则当用Append方法追加时,将会出现错误。

  3.)为了从集合中删除一个由用户定义的属性对象,可以用集合的Delete方法来实现。该方法只能删除用户定义的对象,不能删除预定义属性。

  4.)如果省略了DDL参数,则缺省为False (即非DDL)。在这种情况下,没有出现相应的DDL属性,如果需要将一个Property对象由DDL变为DDL,则必须先删除,然后再重新建立。

  5.)CreateProperty方法中的type参数是一个符号常量,它是Property对象的设置值或返回值,其可能的取值见表3

  type参数的取值

  常数   类型   常数   类型

  dbBigInt Big整型数 dbGUID GUID

  dbBinary 二进制 dbInteger 整型数

  dbBoolean 布尔值 dbLong 长整型数

  dbByte 字节 dbLongBinary 长二进制(OEL对象)

  dbChar 字符 dbMemo Memo

  dbCurrency 货币 dbNumeric 数值

  dbDate 日期/时间 dbsingle 单精度

  dbDecimal 十进制 dbText 文本

  dbDouble 双精度 dbTime 时间

  dbFloat 浮点数 dbTimeStamp TimeStamp

  dbVarBinary VarBinary

设MyDB是一个Database对象变量,MyPro是一个Property对象变量,则可以用下面的程序建立Property对象:

  set MyPro=MyDB.createProperty()

  MyPro.Name="NewDefined"

  MyPro.Type=dbText

  MyPro.Value="这是一个用户定义的属性"

可以用下面的语句把新建立的属性加到Properties集合中:

  MyDB.Properties.Append prpNew

  【例】编写程序,建立用户定义的Property对象,并把它加到Properties集合中。在窗体上画一个命令按钮,然后编写如下的事件过程。

  Private Sub Command1_Click()

   Dim dbsnorthwind As Database

   Dim prpnew As Property

   Dim prploop As Property

   Set dbsnorthwind = OpenDatabase("e:\f.mdb")

   With dbsnorthwind

    '建立并添加用户定义的属性

    Set prpnew = .CreateProperty()

    prpnew.Name = "userdefinednew"

    prpnew.Type = dbText

    prpnew.Value = "this is a user_definednew property."

    .Properties.Append prpnew

    '列出当前数据库的所有属性

    Debug.Print "properties of " & .Name

    For Each prploop In .Properties

    With prploop

     Debug.Print " " & Name

     Debug.Print " type:" & .Type

     Debug.Print " inherited:" & .Inherited

    End With

    Next prploop

    End With

  End Sub

上述程序建立了一个名为userdefinednew的属性,其类型为dbText,初值为“this is a user_definednew property。”运行程序,单击按钮,将建立该属性,并在立即窗口中显示当前数据库的所有属性。(包括新建立的属性)

4.keepLocal属性和Replicable属性
  (1)KeepLocal属性

  KeepLocal属性用来保持对象的本地化,即在复制数据库时,使指定的对象不被复制。性用于Document对象、QueryDef对象和TableDef对象。其设置或返回的值是Text类如果把该属性设置为“T”,则在复制数据库时可使相应的对象保持为本地对象。对象制后,不能使用KeepLocal属性。在获取或设置TableDef或QueryDef的KeepLocal属性之前,必须先用CreateProperty建立,并把它附加到对象的Properties集合中。

  设置了KeepLocal属性后,该属性将出现在Document对象的Properties集合中。KeepLocal通过CreateProperty方法设置。例如:

  Dim dbs As Database

  Dim docTemp As Document

  Dim prpTemp As Property

  Set dbs = OpenDatabase(''dbtemp.m4b``)

  Set docTemp = dbs.Containers(''Modules'').Docu Functions'')

  Set prpTemp = docTemp.Createproperty(''KeepLoc dbText, ''T'')

  docTemp.Properties.Append pWTemp

  dbs.Close

上面的程序把KeepLocal属性附加到Documeni对象的properties集合中去。必须在数据库变为可复制之前设置对象(例如表)的属性。再如:

  Sub SetKeepLocal(tdftemp As TableDef)

   On Error GoTo ErrHandler

   tdfTemp.Properties("KeepLOcal")="T"

   On Error GoTo 0

   Exit Sub

 ErrHandler:

  Dim prpNew As Property

  If Err.Number = 3270 Then

   Set prpNew = tdfTemp.Createproperty("KeepLocal", dbText, "T")

   tdfTemp.Properties.Append prpNew

  Else

   MsgBox "Error" & Err & "." & Error

  End if

  End Sub

上面的过程把指定对象Tab1eDef的KeepLocal属性设置为“T”。如果keepLocal属性不存在,则先建立之,然后把它附加到表的Properties集合中去,并将其值设置为“T”。

  (2)Replicable属性

  Replicable属性用来设置或返回一个值,这个值决定数据库或数据库中的对象是否可以复制(仅Microsoft Jet 工作区)。该属性用于Database对象、Document对象、QueryDef对象和TableDef对象。其设置或返回的值是Text类型。对于Database对象,如果把该属性设置为“T”,则可以复制数据库。设置为“T”后,就不能再改变它,如果把它设置为“F”(或其它非“T”值),则会产生错误。对于数据库中的对象,如果把该属性设置为“T”,则可复制Replicas集合中的所有Replica对象(以及对此对象的更改)。也可以在Microsoft Access的对象属性表中设置该属性。

  在设置一个Database,Tab1eDef或QueryDef对象的Replicable属性前,必须先用

  CreateProperty方法建立它,并把它加入对象的Properties集合中。例如:

  sub CreateReplLocalTableX()

  Dim dbsNorthwind As Database

  Dim tdfNew As TableDef

  Dim fldNew As Field

  Dim prpNew As Property

  Set dbsNorthwind = OpenDatabase("c\dbdir\db3 .mdb")

  '建立一个名为“NewTab”的新TableDef

  Set tdfNew = dbsNorthwind.CreateTableDef("NewTab")

  '定义一个名为“NewField”的文本字段

  Set fldNew = tdfNew.CreateField(“NewField”, dbText, 3)

  '把新字段附加到TableDef中

  tdfNew.Fields.Append fldNew

  '把新TableDef添加到数据库中

  dbsNorthwind.TableDefs.Append tdfNew

  '为新TableDef建立Replicable属性

  Set prpNew = tdfNew.Createproperty(''Replicab , dbText, ''T'')

  '把Replicable 属性加到TableDef中

  tdfNew.Properties.Append prpNew

  dbsNorthwind.Close

  End Sub

上述过程建立一个新的TableDef 对象,并使其可复制。注意,包含该对象的数据库必是可复制的,才能执行此过程。再如:

  Sub SetReplicable(tdryemp As TableDeD)

  On Error GoTo ErrHandier

  tdryemp.PrOperties(''Replicable' = ''T'')

  On Error GoTo 0

  Exii Sub

ErrHandler.

  Dim prpNew As Property

  If Err.Number = 3270 Then

   Set prpNew = tdfTemp.Createproperty(``Replicab , dbText, ''T'')

   idfTemp.Properties.Append prpNew

  Else

   MsgBox “Error” & Err & “:” & Error

  End If

  End sub

上述过程将指定TableDef对象的Replicab1e属性设置为“T”。如果属性不存在,则在错误处理子程序中建立之,然后附加到TableDef的Properties集合中,并设置为“T”。

  5.MaKeReplica方法

  MakeReplica方法用来从一个数据库复本中复制一个新的复本(仅用于Microsoft Jet 工作区)。该方法用于Database对象,其格式如下:

  对象.MakeReplica replica,description,options

  格式中各参数的含义如下:

  ·对象: Database对象变量。

  · rep1ica:是一个字符串,指定新复本的路径和文件名,如果该参数是当前文件名,则会发生错误。

  ·description:是一个字符串,用来描述所生成的复本。

  ·opii0n8:可选。是一个符号常量或常量组合,用来指定所生成的复本的特征,可以取以下两种值:

  dbRepMakepartial生成一个部分复本

  dbRepMakeReadoniy防止修改新复本。但是,当将新复本与复本集中的另一个复本同步时,对设计和数据的修改将传送到新复本

  上述两个常量可以单独使用,也可以用“十”号组合在一起,例如:

  dbRepMakePartial + dbRepMakeReadOnly

所谓建立数据库复本,实际上就是建立数据库的拷贝。通过数据库复制,每个用户都可以使用数据库中数据的一份拷贝,并可在某个时亥把各个数据库重新组合成宿主数据库,而对宿主数据库的修改都传送到数据库复本。注意,数据库复制功能仅对Microsoft Jet 3.5版的数据库有效。
  Microsoft Jet 数据库引擎不允许用数据库密码来保护复制数据库。在开始使用复本之前,必须先从将要复制的数据库中删去所有数据库密码保护。设置用户权限与复本同步没有冲突。

  用DAO复制数据库的一般步骤如下:

  (1)识别数据库中不需要复制的对象,并将它们的KeepLocal属性设置为“T”。

  (2)将数据库的Replicable属性设置为“T”,使它变成设计原版。

  (3)用MakeReplica方法从设计原版中生成附加的复本。

在设置Replicable属性之前,应先确定在转换数据库以前数据库是否已经被复制。

  1.保持对象本地化

  当把正常的数据库转换为设计原版时,将复制数据库中的所有对象。如果不想把数据中的所有对象都放在复本集中,则可对不想复制的对象添加并设置KeepLocal属性。例如,果数据库中有一个表,在该表中含有机密的工资信息、初始化信息或登录到数据库的用名,则可能希望不把这些信息放到复本中。在这种情况下,可将该表的KeepLocal属性设为“T”,使得复制数据库时,这些信息不被复制。

  对于TableDef 和 QueryDef对象,可以建立keepLocal属性并把它添加到对象的属性集合中。对于由主机应用程序定义的窗体、报表、宏以及模块,可以建立KeepLocal属性并把它添加到表示该对象的Document对象的属性集合中。

注意,在设置keepLocal (以及Rep1icab1e )属性之前,必须先建立它,然后添加到将使用它的对象的属性集合中。如果在建立并添加该属性之前先引用了它,则将产生一个运行时错误。
【例】编写一个Function 过程,对数据库中指定的对象进行本地化处理。

  Function SetKeepLocal(dbs As Database, strCollection As String, stffobJect As String) As integer

  Dim i As Integer

  Dim blnMatch As Boolean

  Dim tdf As TableDef

  Dim PrP As Property

  Dim doc As Document

  Dim qdf As QueryDef

  On Error GoTo ErrorHandler

  Select Case stalollection

   Case "FormS", "RelpOrtS", ''MOdllleS'', ''SCriptS`'

     Set doc = dbs.Containers(strCollection). Documents(strObject)

     Set prp = doc.Createproperty ("KeepLocal", dbText, `'T'')

     doc.Properties.Append prp

   Case "TableDefs"

     Set tdf = dbs.TableDefs(strObJect)

     Set prp = tdfCreateproperty (''KeepLocal'', dbText, ''T'')

     tdfprol)etties.Append prp

   Case ''QuecyDefs'`

     Set qdf=dbs.QueryDefs(sbrobject)

     Set prp = qdf.Createproperty ("KeepLocal", dbText, "T")

     qdf.properties.Append PrP

  End Select

ErrorHandler:

  Select Case Err

   Case 0

    case 3265 '对象未发现

    SetKeepLocal = 3265

    Exit Function

    '属性已经存在,把它设置为“T”

   Case 3367

    Select Case sttoollection

     CSSel ''Forms'' , ''RelportS'', ``Modlules'' , ''ScriptS'`

     doc.Properties(''KeepLocal'`).Value = `'T'`

   Case ''TableDefs'`

     tdf.Properties(''KeepLocal'').Value = `'T'`

   Case ''QueryDefs'`

     qdf.Properties(''KeepLocal'').Value = ''T'`

   Exit Function

  End Select

  SetKeepLocal = 0

  Exit Function

  Case Else

   MsgBOx ''Error'' & Err & ":", & Error, vbOKOnly

   SetKeepLocal=-1

   Exit Function

   End Select

  End Function

用上述过程可以对指定数据库对象建立并添加KeepLocal属性,如果该属性已经存在,则将产生代码为3367的错误,在这种情况下,将在错误处理程序中把该属性的值设置为“T”

  该过程有3个参数,其中第一个参数是Database对象,第二个参数是集合的名字,第三个参数是数据库中的对象名。过程的返回值是一个整型数,它实际上是一个错误代码。为了调用上面的过程,可以在窗体上画一个命令按钮,然后编写如下的事件过程:

  Private Sub Command1_Click()

   Dim MyDb As Database

   Dim a As integer

   Set MyDb = OpenDatabase(''c:\dbdir\db1.mdb'')

   a = SetKeepLocal(MyDb, ''TableDefs'',''Tabel1'')

   If a = 0 Then

    MsgBox "已成功设置KeepLocal 属性"

   Elself a = 3265 Then

    MsgBox "对象未找到"

   Elself a = 3367 Then

    MsgBox "KeepLocal属性已存在,设置为“T”

   Else

    MsgBox“出错”

   End lf

  End sub

该事件过程调用SetKeepLocal过程,用来建立并设置数据库db1.mdb的TableDefs集合中Tabel1对象的KeepLocal属性。

  如果已经在数据库的两个表之间建立起关系,则必须将两个表的keepLocal属性设置为相同的值,即两个表都必须是本地的或者是可复制的。如果两个表的keepLocal属性设置不一样,则转换将会失败。但是应注意,不能在关系有效时设置keepLocal属性,也就是说,在设置属性之前,应先删除两个表之间的关系,在设置好KeepLocal属性之后再恢复两个表之间的关系,然后继续进行数据库转换。

  如果正在设置KeepLocal属性的对象已经从其它对象中继承了该属性,则由其它对象设置的值对保留为本地对象的操作没有影响,必须直接为每个对象设置keepLocal属性。


2.使对象可以复制
  如果在复本中建立了一个新对象,并且想把它从本地的改为可复制的,使得其它用户都可以使用它,则需要在设计原版中建立该对象,并且将其Replicab1e属性设置为“T”。在这种情况下,务必删除所有复本中的这个本地对象,否则会产生一个错误。

  对于TableDef和QueryDef对象,可以直接建立Replicab1e属性,并添加到对象的属性集合中,就像处理KeepLocal属性那样。而对于由宿主应用程序所定义的窗体、报表、宏和模块,则应建立Replicable属性,然后添加到表示该对象的Document对象的属性集合中。

  在下一次同步时,新的可复制对象将出现在集合的其它复本中。类似地,如果想把可复制对象改为本地对象,则应将其Replicab1e属性设置为“F”。和KeepLocal属性一样,如果正在设置Replicab1e属性的对象已经从其它对象继承了这个属性,则其它对象设置的值对这个对象不起作用,必须直接对每个对象设置Rep1icab1e属性。

  注意,如果把一个对象的Replicab1e属性从“T”改为“F”,该对象便从可复制状态变为本地的,在这种情况下, Microsoft Jet将只在设计原版中保留该对象,而从复本集的其它复本中删掉。在改变表的可复制状态时,应当格外小心。即使在设计原版中暂时把一个可复制表改变为本地表,然后再改回可复制的,但下次同步时仍然将会在每个复本中删除并重建该表。除非在进行设计变更之前同步所有的复本,否则将会丢失自上次同步以来输入到表中的所有数据。

3.构造设计原版

  设计原版也是一个数据库复本,但它是一个可以复制的复本。为了把一个数据库变为设计原版,需要为Database对象建立Rep1icab1e属性,并把该属性添加到Database对象的属性集合中,然后将其Replicab1e属性设置为“T”。

  【例】编写一个Function过程,把指定的数据库变为设计原版。

  过程如下:

  Public Function SetReplicable(strDB As String)As integer

   Dim prpReplicable As Property

   Dim dbsTarget As Database

   n Error GoTo ErrorHandler

   Set dbsTarget = OpenDatabase(strDB,True)

   ‘若属性已存在,则关闭错误处理

  On Error Resume Next

   ' 创建Replicable 属性

   Set prpReplicable =dbsTarget.Createproperty( "Replicable", dbText, ''T'`)

   '把该属性添加到属性集合中

   dbsTarget.Properties.Append prpReplicable

   '把该属性设置为"T"

   dbsTarget.PrOperties("Replicable")= ''T''

   SetReplicable = 0

 ErrorHandler:

   Select Case Err

    Case 0

     SetReplicable = 0

     Exit Function

    Case Else

     MsgBox "Error" & Err ":" & Error

     SetReplicable = -1

     Exit Function

    End Select

  nd Function

上述过程把指定的数据库转换为设计原版。如果Rep1icab1e属性不存在,则建立该属性,井把它设置为指定的值。

  为了调用上述过程,可以在窗体上画一个命令按钮,然后编写如下的事件过程:

  Private Sub Conunandl_Click()

   Dim MyDB As Database

   Dim a As integer

   a = SetReplicable(''c:\dbdir\dbl .mdb``)

   If a = 0 Then

    MsgBox "成功设置Replicable 属性"

   Else

    MsgBox "设置失败"

   End if

  end sub

运行程序,单击命令按钮,将调用SetReplicable过程,为指定的数据库添加和设置Replicab1e属性,并根据执行情况显示相应的信息。在转换进程中,Microsoft Jet将维持原始数据库的所有属性设置值。



  4.用复本生成复本

  当把数据库的Replicable属性设置为“T”,从而将数据库转换成设计原版时,在复本集中只有一个复本(即设计原版),只能用它来生成第一个复本。可以用MakeReplica方法来生成第一个复本和后续的复本。

  用设计原版生成数据库的第一个复本后,可以用集合中的任一复本来生成另外的复本。事实上,在复本集中增加数据库新备份的唯一途径,就是从一个现存的复本来建立它们。一旦立好,新复本即成为复本集的一部分。所有复本都有唯一的标识,并能相互通信和同步。每个复本集与所有其它复本集是互相独立的,不同复本集的复本不能相互通信或同步。

  注意,在原始数据库的备份被变成设计原版之前,不要用它来生成另外的复本。否则,生成的将不是另外的复本,而是新的设计原版和复本集。

  【例】编写一个过程,用来生成数据库复本。

  过程如下:

  Function MakeAdditionalReplica(strReplica As String, strNewReplica As String, intOptions As         Integer) As integer

   Dim dbs As Database

   On Error GoTo ErrorHandler

   Set dbs = OpenDatabase(strReplicableDB)

   '如果没有选项传递给MakeAdditionalReplilca,

   '就忽略选项参数,该选项参数的缺省值是完全的,读/写复本;

   '否则,使用intoptions的值

   If intOptions = 0 Then

    dbs.MakeReplica strNewReplica, "Replica of " & strReplicableDB

   Else

    dbs.MakeReplica strNewReplica, "Replica of " & strReplicableDB, intOptions

   End if

   dbs.Close

 rrorHandler:

   Select Case Err

    Case 0:

     MakeAdditionalReplica = 0

     Exit Function

    Case Else:

     MsgBox"error" & err ":" & Error

     MakeAdditionalReplica =-1

     Exit function

   End select

  End function

上述过程可以从一个数据库复本生成一个新的复本。该过程有3个参数,其中第一个参数是数据库复本的文件名,第二个参数是新生成的数据库复本的文件名,第三个参数,即intOptions,可以是DAO常数dbRepMakeReadOnly和dbRepMakePartial的组合,也可以是0。 dbRepMakeReadOnly常数表示复本是只读的,而dbRepMakePartial常数表示复本是部分复本,不是完全复本。例如,为了建立一个只读部分复本,在调用过程MakeAdditionalReplica时,应当把dbRepMakeReadon1y + dbRepMakePartial的值传递给intOptions参数。如果intOptions参数是0,则过程将建立一个完全的读/写复本,因为忽略了MakeReplica方法中的options参数。

  为了调用上述过程建立数据库复本,可以在窗体上画一个命令按钮,然后编写如下的事件过程:

  Private Sub Command1_Click()

   A=MakeAdditionalReplica("c:\dbdir\dblcopy1. mdb","c:\dbdir\dblcopy2.mdb",0)

   if a=o Then

    MsgBox"己生成数据库复本"

   Else

    MsgBox“操作失败”

   End lf

  End sub

过程中的dblcopy1.mdb 是数据库db1.mdb的复本,而dblcopy2.mdb是dblcopyl.mdb的复本。运行程序,单击命令按钮,将建立一个完全的读/写复本。

  当Microsoft Jet建立新复本时,新复本将包含源复本的所有数据定义语言属性设置值。后续的复本可以由设计原版或集合中的任一复本来生成。

  在用MakeRep1ica方法复制数据库时,正在复制的对象一定不能是锁定的,否则方法的调用会失败。如果一个对象以设计模式打开或在同步期间被更新,则该对象会被Microsoft Jet锁定。在实际的程序设计中,一定要注意这一点,不要试图从拥有锁定对象的数据库来生成复本。

  注意,生成一个新复本后,将把源复本中的所有可复制对象和属性复制到新复本中。虽然所有链接表也被复制,但如果新复本位于网络上,链接表的路径可能会不正确。因此,一定要对新复本进行测试,以确定是否需要为链接表建立新路径。

页: [1]
© 1999-2008 EvilOctal Security Team