最近,一个程序创建了一个Access db(我们下游合作伙伴的要求),添加了一个包含所有备忘录列的表,然后插入了一堆停止工作的记录。奇怪的是,我可以看到环境没有任何变化,任何差异中也没有任何可能影响它的变化。此外,这在我尝试过的任何机器上都可以重现,无论它是否有 Office,是否有 Office,无论是 32 位还是 64 位。
问题是当您在程序运行后打开数据库时,目标表是空的,而是有一个包含一堆行的 MSysCompactError 表。
这是蒸馏代码:
var connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=corrupt.mdb;Jet OLEDB:Engine Type=5";
// create the db and make a table
var cat = new ADOX.Catalog();
try
{
cat.Create(connectionString);
var tbl = new ADOX.Table();
try
{
tbl.Name = "tbl";
tbl.Columns.Append("a", ADOX.DataTypeEnum.adLongVarWChar);
cat.Tables.Append(tbl);
}
finally
{
Marshal.ReleaseComObject(tbl);
}
}
finally
{
cat.ActiveConnection.Close();
Marshal.ReleaseComObject(cat);
}
using (var connection = new OleDbConnection(connectionString))
{
connection.Open();
// insert a value
using (var cmd = new OleDbCommand("INSERT INTO [tbl] VALUES ( 'x' )", connection))
cmd.ExecuteNonQuery();
}
以下是我偶然发现的一些解决方法:
- 如果在创建表和插入值之间插入断点(上面的第 28 行),然后使用 Access 打开 mdb 并再次关闭它,那么当应用程序继续运行时,它不会损坏数据库。
- 将引擎类型从 5 更改为 4(第 1 行)将创建一个未损坏的 mdb。您最终会得到一个过时的 mdb 版本,但该表有值并且没有 MSysCompactError。请注意,我尝试过以这种方式创建数据库,然后最后以编程方式将其升级到 5,但没有成功。我最终在最新版本中得到了一个损坏的数据库。
adLongVarWChar
如果您通过将第13 行更改为 将备注更改为文本字段adVarWChar
,则数据库没有损坏。不过,您最终text
会得到 db 中的字段而不是memo
。
最后一点:在我的旅行中,我看到 MSysCompactError 与压缩数据库有关,但我没有做任何明确的事情来使数据库紧凑。
有任何想法吗?