我正在将DBF + DBT文件转换为SQL。我使用Microsoft.Jet.OLEDB.4.0连接器访问文件和SqlConnector用于在MS SQL中写入数据,以提高性能我使用SqlBulkCopy方法。大多数文件转换得很好,但在某些方法上,SqlBulkCopy.WriteToServer抛出异常:
记录已删除。 在任何记录中都找不到搜索关键字。
复制操作没有完成,我在SQL中遗漏了很多记录。
有没有办法绕过这个问题,还是我想放弃SqlBulkCopy并一行一行地复制?
编辑: 所以我决定PACK数据库,但到目前为止没有运气。当我使用vfpoledb进行阅读时,由于投射小数的某些问题,它会更快崩溃。所以我想首先使用PACK(使用vfpoledb)然后使用JetOleDb reader.Even虽然执行了PACK,但我可以看到dbf和dbt文件发生了变化,reader.GetValues()仍在抛出同样的例外。
try
{
string file = @"f:\Elims\dsm\CPAGEMET.DBF";
string tableName = Path.GetFileNameWithoutExtension(file);
var dbfConnectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='dBASE III;DELETED=YES;HDR=NO;IMEX=1'", Path.GetDirectoryName(file));
var packConnString = string.Format(@"Provider=vfpoledb;Data Source={0};Collating Sequence=machine;", file);
OleDbConnection packConnector = new OleDbConnection(packConnString);
packConnector.Open();
OleDbCommand command = new OleDbCommand(string.Format("PACK {0}",tableName), packConnector);
var result = command.ExecuteNonQuery();
packConnector.Close();
OleDbConnection oleConnector = new OleDbConnection(dbfConnectionString);
oleConnector.Open();
string cmd = string.Format("SELECT * FROM [{0}]", tableName);
var oleDbCommand = new OleDbCommand(cmd, oleConnector);
OleDbDataReader dataReader = oleDbCommand.ExecuteReader();
object[] values = new object[dataReader.FieldCount];
int iRow = 0;
while (dataReader.Read())
{
iRow++;
Console.WriteLine("Row " + iRow);
dataReader.GetValues(values);
}
oleConnector.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message + e.StackTrace);
}
由于
答案 0 :(得分:1)
看起来有些记录被标记为已删除。如果您需要这些记录,请将其还原,或者如果您不需要这些记录,则永久删除它们(使用PACK命令)。
答案 1 :(得分:0)
所以经过一番挖掘,我得出了最后的解决方案,所以我将总结一下我的发现。 “删除记录”异常非常具有误导性,因为问题实际上从未被删除过记录。有3个空行,实际上是触发了异常。一旦这些被删除,一切都开始工作,我甚至不必打包数据库。这适用于我使用Microsoft.Jet.OLEDB连接器的场景。
我尝试使用vfpoledb连接器,但我遇到了十进制数的其他问题。我写了一个灵感来自this msdn discussion的修复程序,不仅一切都开始工作(因此删除并成功跳过空行),而且导入现在比使用Jet连接器快15倍(再次使用BulkCopy)