Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2253870
  • 博文数量: 292
  • 博客积分: 10016
  • 博客等级: 中将
  • 技术积分: 3381
  • 用 户 组: 普通用户
  • 注册时间: 2005-11-06 11:26
文章分类

全部博文(292)

文章存档

2011年(1)

2010年(4)

2009年(3)

2008年(6)

2007年(47)

2006年(63)

2005年(168)

分类: LINUX

2005-12-14 22:27:37

这篇文章中的信息适用于:
Microsoft Access 2000

本文的发布号曾为 CHS209137
初学者:要求具备单用户计算机的用户界面知识。

本文仅适用于 Microsoft Access 数据库 (.mdb)。

概要
各种环境因素有可能损坏数据库文件。被破坏的数据库的症状包括:某些记录显示 #Deleted;无法打开数据库中的某个对象,以及无法在 Access 中打开该文件。Microsoft Access 2000 中的修复和压缩工具是恢复和优化 Microsoft Access 数据库文件的有效工具。本文说明如何使用这些 Access 2000 工具以及其它修复损坏数据库的方法。另外,还给出了数据库损坏原因的信息。
更多信息
尽管本文所描述的步骤通常可成功地恢复已损坏的数据库文件,但为了保护数据,应当在条件允许的情况下经常备份数据库文件。
压缩和修复工具


压缩工具可消除现有数据库中的未占用空间。它是通过创建一个新的目标数据库,并将旧数据库中的所有对象复制到新数据库中来实现的。如果您选择将数据库压缩到原来的数据库名称下,而不是新的数据库,那么压缩工具将会创建一个临时数据库,将原数据库中的所有对象导出到临时数据库中,删除原来的数据库,然后将临时数据库重命名为原来的数据库。

修复工具只用来修复数据库中的表、查询和索引。它不能修复已损坏的窗体、报表、宏或模块。以下是压缩工具所执行的操作列表。

●重新组织表的页面,使之放在相邻的数据库页面上。由于表不再散放在数据库中,所以可提高性能。
●回收对象和记录删除创建的未使用的空间。当从数据库中删除对象或记录时,就会将它们所占用的空间打上标记,提供给数据库新添加项使用。但是,除非对数据库进行压缩,否则数据库不会变小。对于经常添加、删除和更新对象及记录的数据库而言,应该经常对数据库进行压缩。
●重新递增 AutoNumber 字段,使分配的下一个值比其余记录的最大值大 1。例如,如果删除了数据库中的所有记录,在压缩数据库后添加下一个记录时,AutoNumber 字段中的值将为 1。如果数据库中 AutoNumber 最大余值为 50,那么在压缩值后添加下一个记录时,它的值为 51。注意,即使压缩之前添加的记录包含的值大于 50,它也适用。
●重新生成查询优化过程使用的表统计数字。通常,如果回滚事务、由于断电而没有正常关闭数据库或者关机前无法完全退出使用 Microsoft Jet 的程序,这些统计数字可能会随时间而过时。
●标记所有的查询,以便下次执行查询时重新进行编译。这一点很重要,因为数据库统计数字可以会发生变化,并且以前编译的查询的查询计划可能不准确。

运行压缩和修复工具的重要原则


在对数据库运行压缩和修复工具之前,必须满足以下条件:

必须使用对数据库中所有表具有“修改设计”或“管理”安全权限的帐户登录。

必须给原始和压缩后的数据库留有足够的磁盘空间,即使数据库是通过 Microsoft Access 2000 用户界面以相同的文件名压缩的,也是如此。仅当压缩成功时,才可以将修复/压缩的数据库重命名为原来的数据库名。

其它用户不可打开数据库。当数据库被压缩时,它必须由 Microsoft Jet 以独占方式打开,以防止在压缩过程中任何用户访问和修改数据库。
恢复已损坏的数据库


以下步骤概括了修复已损坏数据库的一般方法:
1、备份已损坏数据库 (.mdb) 文件。
2、如果有.ldb 文件,请删除它。删除此文件之前应关闭相应的 .mdb 文件。

.ldb 文件用于确定共享数据库中锁定了哪些记录以及是由谁锁定的。如果以共享模式打开数据库来,那么就会创建一个与相应的数据库 (.mdb) 同名的 .ldb 文件。例如,如果在 c:MsofficeAccess 文件夹内打开(共享使用)示例数据库 Northwind.mdb,则会在同一文件夹内自动创建文件 Northwind.ldb。当最后一个用户退出数据库后,.ldb 文件被自动删除,但有两种例外情况 — 一种情况是最后一个用户对含有.mdb文件的文件夹没有删除权限,另一种情况是数据库被破坏。.ldb 文件包含打开数据库的用户列表。

有时,要找出数据库破坏的原因,必须检查是谁登录到数据库中。可以使用 Access 2000 中的 Microsoft Visual Basic for Applications,输出登录到特定数据库中的用户列表,


3、按照下列方法运行压缩和修复工具:
a、如果数据库被打开,请先关闭它。
b、在工具菜单上,指向数据库实用工具,然后单击压缩和修复数据库。
c、在压缩数据库来源对话框中,选择要压缩的文件,然后单击压缩。
d、在压缩数据库为对话框中,输入新的文件名并单击保存。

如果压缩和修复不成功,将会有提示信息说明此情况。这就意味着损坏非常严重,无法将其修复。
4、如果上述步骤无法恢复被损坏的数据库,请试着创建一个新数据库,将旧数据库中的对象逐个导入新数据库中。然后重新创建关系。这种方法可解决数据库中系统表损坏的情况。

注意,不能用“导入向导”导入数据访问页。但可以在新数据库中打开现有的数据访问页。为此,请执行下列步骤:
a、在“数据库”窗口,在对象下单击页面。
b、单击新建按钮。
c、在新数据访问页对话框,单击现有 Web 页,然后单击确定。
5、如果表损坏,并且以上步骤不能将它恢复,请尝试以下步骤:

a、从 Microsoft Access 2000 中,将表导出为 ASCII(分隔的文本)文件。有关此主题的详细信息,请搜索“分隔的文本”短语,然后使用 Microsoft Access 帮助索引查看“导出 Access 数据”。
b、删除与该表关联的所有关系,然后从数据库中删除该表。
c、压缩此数据库。
d、重新创建该表及其与之关联的任何关系。
e、使用字处理器检查 ASCII 文件是否有错误或反常的数据,并删除这些记录。以 ASCII 文本文件格式保存该文件。
f、重新将 ASCII 文件导入到新创建的表中。有关此主题的详细信息,请搜索“分隔的文本”短语,然后使用 Microsoft Access 帮助索引查看“导入或链接”。
g、重新输入已被迫删除的任何记录。
6、如果窗体或报表损坏,则可能是窗体或报表本身损坏,或者它们中的一个或多个控件损坏。您可以删除窗体或报表,然后再从数据库的备份副本中导入它,也可使用以下某个选项:
●如果这种损坏发生在窗体或报表本身,那么可创建一个新窗体或新报表,然后从原来的窗体或报表中复制其控件。
●如果这种损坏发生在窗体或报表的某个控件,那么可创建一个新窗体或新报表,然后在新窗体或新报表上重新创建控件。最好能够创建所有的控件,因为无法识别到底哪个控件受到损坏。
7、如果宏或模块受到损坏,这种损坏可能发生在宏或模块本身,也可能发生在宏或模块的内容上。您可以删除宏或模块,然后再从数据库的备份副本导入它,也可使用以下某个选项:
●如果这种损坏发生在宏或模块本身,那么可创建一个新的宏或模块,然后复制原来的宏或模块的内容。
●这种损坏可能涉及嵌入到模块中的非 ASCII 字符。将模块保存为一个文本文件,删除所有错误或乱码数据,然后将此文本文件重新加载到新模块中。
●如果这种损坏发生在宏或模块的内容上,则必须创建一个新的宏或模块,然后重新创建原来的宏或模块的内容。
8、如果表损坏,并且以上步骤不能将它恢复,则执行以下步骤:

a、从 Microsoft Access 中,将表导出为 ASCII(分隔的文本)文件。有关此主题的详细信息,请搜索“分隔的文本”短语,然后使用 Microsoft Access 帮助索引查看“导出 Access 数据”。
b、删除与表关联的任何关系,然后从数据库中删除该表。
c、压缩此数据库。
d、重新创建该表及其关联的任何关系。
e、使用字处理器,检查 ASCII 文件是否有错误或反常的数据,并删除这些记录。以 ASCII 文本文件格式保存该文件。
f、重新将 ASCII 文件导入到新创建的表中。有关此主题的详细信息,请搜索“分隔的文本”短语,然后使用 Microsoft Access 帮助索引查看“导入或链接”。
g、重新输入已被迫删除的任何记录。
如果采取上述步骤仍然不能修复,那么可能确实无法修复该数据库了。如果出现这种情况,那么应恢复上次备份的数据库,或者重新创建数据库。

最后的选择方法是,某些专家可能会提供 Microsoft Access 数据库修复服务。由于这是一种很特殊的服务,找到这类专家的最有效的途径是在 Microsoft Access “第三方和用户组” Internet 新闻组中发布一则消息,新闻组的地址是:
microsoft.public..3rdpartyusrgrp

有关 Microsoft Access Internet 新闻组的详细信息,请参见 Microsoft Knowledge Base 中的下列文章:
150057 Internet 上可用的 Microsoft Access 新闻组

.mdb 文件损坏的常见原因


Access/Jet mdb 文件损坏有三个主要原因。

由于写入操作被中断使数据库处于置疑/损坏状态


强烈建议通过单击“文件”菜单上的“退出”或“关闭”,正常关闭数据库。但是,如果 Access 不正常关闭时,数据库正处于打开状态并正在写数据,则 Jet Database Engine 就会将该文件标记为置疑/损坏。如果手动关闭机器之前没有先关闭 Windows 或者断电,也可能会出现这种情况。其它情形还包括:在打开数据库的同时,没有关闭 Access 但仍干扰 Jet 向磁盘写入数据。例如,当网络遇到数据冲突或者磁盘驱动器故障时,就会出现这种情况。如果发生任何此类中断,Jet 就会将数据库标记为可能已被破坏。

当 Jet 开始写操作时,将设置一个标记,并在操作完成时重新设置该标记。如果写操作被中断,标记保持不变。当您要再次打开数据库时,Jet 确定标记是否已设置并报告数据库是否被破坏。在大多数情况下,数据库中的数据实际上没有被破坏,但设置的标记提醒 Jet 数据库可能已被破坏。如果是这种情况,压缩和/或修复数据库通常可以还原数据库。所幸的是,有办法确定哪些用户和工作站负责将文件标记为置疑。有关确定哪些用户和/或工作站使 Jet 将文件标记为置疑,请参见本文后面的“方法”。


网络硬件故障


在这种情况下,文件损坏与 Jet Engine 无关;文件损坏完全是由于外界原因造成的。原因可能是由于存放数据库的计算机和打开数据库的计算机之间的硬件链中的一个或多个链接出故障。此列表包括但不局限于网卡、网络电缆、路由器和集线器。

通常,mdb 文件指示由硬件造成的损坏不能通过使用压缩、修复或 Jetcomp 来还原。直到出故障的硬件被修复或替换,硬件损坏才会被修复。


在另一个程序中打开和保存 mdb 文件


当打开一个 mdb 文件并在另一个程序中保存时,不能恢复该文件。例如,Microsoft Word 允许打开并保存 Access 数据库(顺便提一下,如果在另一个应用程序中打开 MDB 文件,这样做不起任何作用,因为您看到的都是扩展字符)。当这样保存 mdb 文件时,如果在 Access 中打开它,就会提示您输入数据库密码,即使文件在 Access 中从未使用密码保护,也是如此。此处出现密码提示的原因是:当 Access 打开文件时,检查的第一个字节范围就是数据库密码所在的位置。如果该字节包含损坏的数据,Access 就会认为该文件受密码保护。即使能够绕过此处的密码提示,数据库仍无法恢复,因为二进制结构是混乱的,Access 根本无法读取。在这种情况下,恢复文件的备份副本是唯一的解决方法。有关这一问题的详细信息,请单击以下文章编号,查看 Microsoft Knowledge Base 中的相应文章:
243895 ACC2000:出现数据库密码,虽然从前从未设置过

如何确定哪些用户/工作站负责将文件标记为置疑


有时,要找出数据库被破坏的原因,必须检查是谁登录到数据库中。可以使用 Access 2000 中的 Microsoft Visual Basic for Applications,输出登录到特定数据库中的用户列表,


防止出现破坏可以采取的步骤


●在数据库写入过程中避免断电。断电将使数据库处于置疑状态。
●避免网络连接断开。
●避免不正常断开 Microsoft Jet 连接,如断电、手动关闭、使用任务管理器关闭应用程序等。
●编程时应关闭所有打开的 DAO 和 ADO 对象。示例包括:Recordset、QueryDef、TableDef 和 Database 对象。

●致命系统错误几乎总是导致不正常始止。如果数据库容易出现致命错误,则在数据库由于破坏严重而无法打开或恢复之前,应该消除这些错误。

●经常压缩此数据库。
●不要在 Windows NT Server 上运行 IPX,其中 Jet 数据库放在网络上,而客户机使用带有 IPX/SPX 的 Microsoft Windows 95。而是在 Windows NT Server 上运行 TCP-IP,而在 Win95 客户机上运行双协议栈 IPX 和 TCP-IP。(Windows NT 对 Windows NT + IPX/SPX 不会出现问题,客户机采用 Novell 也不会出现问题。)
●避免在循环中使用大量打开/关闭操作(40,000 次连续的打开/关闭操作到 1,000,000 次以上)。
参考
有关修复数据库的详细信息,请单击帮助菜单上的 Microsoft Access 帮助,在“Office 助手”或“操作向导”中输入修复,然后单击搜索查看该主题。


现在我们已经讨论了中级SQL的语法,那么让我们看看在一个Access应用程序中我们可以使用它的一些途径。

数据库范例
作为这篇文章的附带,这里有一个叫acIntSQL.mdb的数据库范例。

在acIntSQL中的任一处都是基于本文所提到的所有主题,并且它通过查询和范例的代码演示了我们所讨论的不同SQL语句。

在acIntSQL中所使用到的许多部分查询都是基于特定工作表中存在和包含的数据,或者是基于其它已经存在的数据库对象。如果你由于丢失数据而在运行一个查询产生故障,打开工作表重置窗体并单击工作表重置按键。这将会重新生产工作表和其中原始缺省数据。如果要手动通过工作表重置过程,你需要按照下面的顺序执行这些查询过程:

Drop Table Shipping
Drop Table Invoices
Drop Table Customers
Drop Table CreditLimit
Create Table Customers
Create Table Invoices
Create Table Shipping
Create Table CreditLimit
Populate Customers
Populate Invoices
Populate Shipping
Populate CreditLimit

查询
查询就是指存储在Access数据库中并可以随时调用的SQL 语句,也可以直接被Access 用户界面或Visual Basic® for Applications (VBA)编程语言调用。查询可以使用Access Query Designer来建立,Access Query Designer时一个可以很容易建立SQL语句的强大的可视化工具。或者你也可以通过直接在SQL视图窗口输入SQL语句来建立查询。

如同在"Microsoft Jet SQL for Access 2000基础篇"一文中所述, Access把数据库中所有面向数据的任务转化为SQL 语句。要演示这一点,让我们使用Access Query Designer来建立一个查询。

打开acIntSQL数据库。
(单击此处拷贝acIntSQL.mdb 数据库例子。)

确保tblCustomers 和 tblInvoices这两个表单已经创建并且其中包含有数据。
在数据库窗口中从Objects条中选择Queries选项。
在数据库窗口工具条里单击按键 New。
在New Query对话框中选择Design View并单击OK。
在Show Table对话框中选择tblCustomers并单击Add;接着选择tblInvoices 并单击Add;接着单击Close按键。
在tblCustomers 域名列表中选择Last Name 域并把它拖到设计表格中的第一个域中。
在tblInvoices 域名列表中选择InvoiceDate 和 Amount域并把它们拖到设计表格中。
在设计表格中InvoicwDate域的Sort属性里选择Ascending。
从Access菜单条中选择View并单击SQL View。这样就打开了SQL View 窗口和显示了在查询中Access正在使用的SQL语法。
注意 这个查询类似于存储在acIntSQL 数据库中的"Join - Inner"查询。

嵌入语句
嵌入SQL 语句就是指你在Visual Basic for Applications (VBA) 编程语言中使用SQL 语句。虽然深入讨论如何使用VBA超出了本文的范围,但如何使用程序来运行SQL 语句却是一件简单的工作。

在acIntSQL数据库中,有两个使用内部SQL语句的窗体需要通过Jet OLE DB provider 和 ADO来运行:就是演示数据定义语句的 Intermediate DDL 窗体,以及演示数据处理语句的Intermediate DML窗体。

中级DDL 语句
这个acIntSQL数据库有许多关于你可以用来管理你的数据库结构的SQL 语句的范例。有一部分数据定义语言 (DDL) 语句被以数据定义查询的方式存储。而其它的则在程序设计代码的内部作为内联SQL使用。如果你要使用这些DDL例子,你需要在运行它之前删除一些数据库对象。例如,如果你想运行创建当前数据类型的查询,你就先要确定当前数据表单不存在。如果不是,那么,这个查询就会返回一个信息告诉你这个表单已经存在。在运行任何DDL 例子之前,检查它所要创建或改变的数据库对象确定其已经被设定好,这样程序才能完全的运行。

在内联DDL 语句范例中,同样的建议仍然是适用的:检查并设定它们会影响的数据库对象以确保DDL 语句的顺利运行。

一般来说,内联DDL 语句只是通过简单设定一个ADO Connection对象来运行,并将SQL 语句传送给 Connection对象的运行程序。下面是来源于在中级DDL语句窗体的二进制数据类型的输入输出。

Private Sub cmdBinary_Click() Dim conDatabase As ADODB.Connection
Dim SQL As String
On Error GoTo Error_Handler
Set conDatabase = Application.CurrentProject.Connection
'注意: Fields 1 through 4 can be created through both
'SQL View and the Jet OLEDB Provider.
'Fields 5 and 6 can only be created through the
'Jet OLE DB provider.

SQL = "CREATE TABLE tblCodeBinaryDataTypes (" & _
"Field1_BINARY BINARY, " & _
"Field2_BINARY250 BINARY(250), " & _
"Field3_VARBINARY VARBINARY, " & _
"Field4_VARBINARY250 VARBINARY(250), " & _
"Field5_BVARYING BINARY VARYING, " & _
"Field6_BVARYING250 BINARY VARYING(250))"
conDatabase.Execute SQL
MsgBox "The BINARY datatypes table has been created!"
conDatabase.Close
Set conDatabase = Nothing
Exit Sub
Error_Handler:
MsgBox Err.Description, vbInformation
End Sub




运行过其中一个DDL 语句后,在设计视图中打开被影响的数据库查看产生了什么变动。如果DDL 语句影响了表单之间的关联,打开编辑关联窗口查看其变动。例如让我们检查一下在中级DDL语句窗体中的Alter Table w/ Fast Foreign Key输出指令和按键。
打开acIntSQL 数据库。
确定tblCustomers 和 tblInvoices 表单已经被创建。
在数据库窗口从Objects条中选择Forms。
在数据库窗口工具条中着重显示Intermediate DDL 语句的窗体并单击Design按键。
在Intermediate DDL 语句窗体中,鼠标右键点击Alter Table w/ Fast Foreign Key按键并从弹出菜单中选择 Build Event…。这操作将打开VBA开发环境以及包含着cmdFastKey_Click子过程的代码窗口。
检查被分配给 SQL变量的SQL 语句。
SQL = "ALTER TABLE tblInvoices " & _
"ADD CONSTRAINT FK_tblInvoices " & _
"FOREIGN KEY NO INDEX (CustomerID) REFERENCES " & _
"tblCustomers (CustomerID) " & _
"ON UPDATE CASCADE " & _
"ON DELETE CASCADE"


注意 DDL 语句改变了tblInvoices 表单并添加了牢固的外关键字限制。同时它也通过使用级联子句在tblInvoices 和 tblCustomers 之间建立了一个数据关联。

关闭VBA 开发环境。
关闭Intermediate DDL 语句窗体。
从Tools菜单中,选择Relationships…菜单项以打开关联窗口。
双击tblCustomers 和 tblInvoices 之间的关联链接以打开Edit Relationships对话框。
注意级联性更新和删除选项没有被设置。
关闭对话框。
当关联链接仍然显示时,按Delete键删除联接。
关闭关联窗口。
如果Intermediate DDL 语句在数据库窗口仍然显示,点击数据库窗口工具条中的Open按键。
点击Alter Table w/ Fast Foreign Key按键产生一个外关键字联系。
关闭Intermediate DDL 语句窗体。
当新的关系链接被创建后,使用前面提到的步骤打开Edit Relationships对话框。
注意级联性更新和删除选项已经被设置。
中级 DML 语句
这个acIntSQL数据库有许多关于数据处理语言 (DML) 语句的例子,在这些范例里你可以用它们来找到数据,并且它们中的大多数是以查询的形式实现的。仅有的以在线SQL形式实现的DML 语句则是基于中级DML 语句窗体的。窗体中的三个例子在LIKE子句中使用"_" 和 "%" 通配符,并使用SELECT INTO 语句在一个外部数据库中创建一个表单。

在acIntSQL 数据库中保存的两个查询是属于DML 语句内容却执行类似DDL的操作。其中的SELECT INTO 语句从已有的数据库中找到数据并用这些数据创建新的工作表。通过这些范例的学习,你将学会如何删除目标工作表,前提是这些工作表已经存在。

在中级DML语句的窗体中的Create Customers Database输出指令和按键展示了一个对SELECT INTO 语句的有趣应用。这是一个告诉你使用中级SQL 语句所能完成的各种事情的一个好的例子。下面就是关于输出命令和按键的子过程的代码:

Private Sub cmdCreateDB_Click()
Dim conCatalog As ADOX.Catalog
Dim conDatabase As ADODB.Connection
Dim SQL As String
Dim sDBName As String
On Error GoTo Error_Handler
'Initialize objects & variables.
Set conDatabase = Application.CurrentProject.Connection
Set conCatalog = New ADOX.Catalog
sDBName = "C:Customers.mdb"
'Create the Customers database.
conCatalog.Create "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & sDBName
'Run the DML statement to build the Customers table.
SQL = "SELECT * INTO tblCustomers IN '" & sDBName & _
"'" & "FROM tblCustomers"
conDatabase.Execute SQL
MsgBox "The new CUSTOMERS database has been created " & _
"as " & sDBName & ".", vbInformation
conDatabase.Close
Set conDatabase = Nothing
Set conCatalog = Nothing
Exit Sub
Error_Handler:
MsgBox Err.Description, vbInformation
End Sub


如果客户数据库已经存在,那么代码将返回一个信息告诉你这个数据库无法被创建。让我们逐步的运行这个代码来看看它都做了什么。

坚持你的C:驱动器确定Customers.mdb文件不存在,如果存在就删除它。
打开acIntSQL 数据库。
确定tblCustomers数据库已经被创建并且此数据库已经装载了数据。
在数据库窗口从Objects条中选择Forms。
在数据库窗口工具条中着重显示Intermediate DM 语句的窗体并单击Open按键。
单击Create Customers Database按键创建新的数据库。
切换到资源管理器查看你的C盘驱动器内容。Customers.mdb 数据库文件应该已经被创建。
双击Customers.mdb数据库文件以打开另一个Access实例。
打开tblCustomers 数据库。注意它所包含的数据和 acIntSQL 数据库里的tblCustomers 所包含的数据相同。
这个产生新的数据库的代码范例是通过Jet OLE DB provider使用ADOX 对象库来创建Access数据库。对于ADOX 对象库的讨论已经超出了本文的范围。如果你想知道更多关于它的信息,在Access 2000 在线帮助中查找"Microsoft ActiveX Data Objects (ADO)"并打开其目录直到你看见"Microsoft ADO Extensions for DDL和 Security (ADOX) Programmer's Reference"。
阅读(1699) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~