是否可以以某种方式以编程方式“压缩和修复”Access 数据库(使用 ADOX、使用 OleDbConnection 等)?
7 回答
我没有足够的代表来回复以前的“答案”,但我想提供一些可能对其他人有关 OP 问题的信息有所帮助。
多年来,我一直使用 JRO 方法从 VB.net 压缩/修复我的 Access 2000 数据库。每隔一段时间,我就有一个客户端设法破坏了数据库(通常是通过网络连接到数据库并且他们遭受意外的网络中断)。只要数据库没有损坏,JRO(根据我的经验)就可以正常工作。如果我使用 Access 应用程序来修复数据库,我永远无法弄清楚为什么可以修复数据库,但是当使用我的应用程序(使用 JRO)时,压缩/修复总是会失败(数据库的格式无法识别)。
因此,在一小时前遇到这个线程后,我在我的应用程序中删除了对 DAO 的引用,并尝试了它修复损坏数据库的能力,因为我今天刚刚有一个客户损坏了他们的数据库(大约 8 年内第三次发生)。猜猜看,当 JRO 失败时,DAO 能够修复数据库!
好的,这就是我对 JRO 与 DAO 的经验。希望能帮助到你。下面是一段CompactDatabase
从 DAO 使用的示例代码:
Dim dbCorrupt As String = "c:\CorruptedDB.mdb"
Dim dbRepaired As String = Path.Combine(Path.GetDirectoryName(dbPath), Path.GetFileNameWithoutExtension(dbPath) & "_Repaired.mdb")
Dim dao As New dao.DBEngine
dao.CompactDatabase(dbCorrupt, dbRepaired)
在 c#.net 中只有四行代码
首先使用一个库:
using JRO;
您想test.mdb
使用以下代码进行压缩和修复:
string currentdirectory = System.IO.Directory.GetCurrentDirectory();
string oldmdbfile = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + currentdirectory + "\\test.mdb;Jet OLEDB:Database Password='xyz'";
string newmdbfile = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + currentdirectory + "\\test1.mdb;Jet OLEDB:Database Password='xyz'";
string oldmdbfilepath = currentdirectory + "\\test.mdb";
string newmdbfilepath = currentdirectory + "\\test1.mdb";
JRO.JetEngine engine = new JetEngine();
engine.CompactDatabase(oldmdbfile, newmdbfile);
File.Delete(oldmdbfilepath);
File.Move(newmdbfilepath, oldmdbfilepath);
MessageBox.Show("Database compact and repaired successfully !",);
因此test.mdb
将被压缩和修复,并test1.mdb
创建一个新文件。然后你只需要删除test.mdb
并重命名test1.mdb
为test.mdb
.
可以通过两种方式压缩和修复 MS ACCESS 数据库:
- 使用 DAO:在 DAO350 中有一个方法
RepairDatabase()
,而在 DAO360 中有CompactDatabase()
- 使用 MDAC+JRO:
例如,在 VB6 (old, old, old...) 中执行以下操作:
Dim jro As jro.JetEngine
Set jro = New jro.JetEngine
jro.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\db_to_repair.mdb;Jet OLEDB:Database Password=mypass", _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\repaired_db.mdb;Jet OLEDB:Engine Type=4;Jet OLEDB:Database Password=mypass"
您会注意到,该函数要求您指定要修复的数据库的名称和修复后的数据库的名称。
VBScript 的示例代码。
Dim objEngine
Dim objProcess
'Dim objDB
Dim strDb1
Dim strPath
Dim strFile
Dim strDAOversion
Dim strApplicationName
Dim strErr
Dim strMsg
Dim FSO
strPath = "C:\Docs\"
strFile = "Some.mdb"
strDb1 = strPath & strFile
Set FSO=CreateObject("Scripting.FileSystemObject")
strDAOversion = "DAO.DBEngine.36"
strApplicationName = "Some.mdb"
strMsg = "About to perform a COMPACT on "
strMsg = strMsg & chr(10) & chr(10)
strmsg = strMsg & strApplicationName
strMsg = strMsg & chr(10) & chr(10)
strmsg = strmsg & "Please ask everyone to EXIT THE SYSTEM."
strMsg = strmsg & chr(10) & chr(10)
strmsg = strmsg & space(12) & "It is VITAL you do not exit windows until"
strMsg = strMsg & chr(10)
strMsg = strMsg & space(12) & "you receive the confirmation message."
strMsg = strmsg & chr(10) & chr(10)
strMsg = strMsg & space(6) & "Press OK to continue or Cancel to stop the process."
If MsgBox(strMsg, 1, strApplicationName) = 1 Then
Set objEngine = WScript.CreateObject(strDAOversion)
Call CompactDB(FSO, objEngine, strDb1, "password")
If strErr="True" Then
strMsg = "Please correct the problem and try again."
MsgBox strMsg, 1, strApplicationName
Else
strMsg = "Database compacting complete."
MsgBox strMsg, 1, strApplicationName
End If
End If
Function CompactDB(objFSO, objEngine, strDb, pwd)
'Compact the database
Dim strdbtemp
Dim MsgText
strdbtemp = Left(strDb, Len(strDb) - 3) & "ldb"
If FSO.FileExists(strdbtemp) = True Then 'if ldb file exists, db is still open.
MsgText = "You have not exited the file. Please close and try again."
MsgBox MsgText, 1, strApplicationName
strErr="True"
Exit Function
End If
If FSO.FileExists(strDb1) = False Then
MsgText = "Cannot locate the database at " & strDB
MsgBox MsgText, 1, strApplicationName
strErr="True"
Exit Function
End If
strdbtemp = Left(strDb, Len(strDb) - 3) & "tmp"
If pwd = "" Then
objEngine.CompactDatabase strDb, strdbtemp
Else
objEngine.CompactDatabase strDb, strdbtemp, , , ";pwd=" & pwd
End If
If Err = 0 Then
FSO.deletefile strDb
FSO.copyfile strdbtemp,strDb
FSO.deletefile strdbtemp
Else
MsgText = "Error during COMPACT process for " & strDB
MsgBox MsgText, 1, strApplicationName
strErr="True"
End If
End Function
此解决方案适用于 Access 2010 数据库引擎:
所需参考:
Microsoft.Office.interop.access.dao
代码:
public void CompactDb(
string sourceFilePath, string destFilePath, string password)
{
var dbEngine = new Microsoft.Office.Interop.Access.Dao.DBEngine();
dbEngine.CompactDatabase(sourceFilePath, destFilePath,
";pwd=" + password, null, ";pwd=" + password);
}
(sourceFilePath 和 destFilePath 不应该相同!)
CompactDatabase 方法参数(来自反射):
void CompactDatabase(
string SrcName, string DstName,
object DstLocale = Type.Missing,
object Options = Type.Missing,
object SrcLocale = Type.Missing);
确保在与您安装的 AccessDatabaseEngine(或 Office)相同的平台下运行它(x86/x64)。
这是官方的 MS 链接,任何进一步的评论都是多余的。 DBEngine.CompactDatabase 方法
添加参考:Microsoft ActiveX 数据对象 2.x 库 Microsoft Jet 和复制对象 2.x 库
sDB = "c:\DB\myDb.mdb"
sDBtmp = "c:\DB\tempMyDb.mdb"
sPASSWORD = "password"
Dim oApp As Access.Application
Set oApp = New Access.Application
Call oApp.DBEngine.CompactDatabase(sDB, sDBtmp, dbLangGeneral, , ";pwd=" & sPASSWORD)
'wait for the app to finish
DoEvents
'remove the uncompressed original
Kill sDB
'rename the compressed file to the original to restore for other functions
Name sDBtmp As sDB