【问题标题】:SqlBulkCopy WriteToServer throws an exception Record is deletedSqlBulkCopy WriteToServer 抛出异常记录被删除
【发布时间】:2014-03-12 10:52:25
【问题描述】:

我正在将 DBF + DBT 文件转换为 SQL。我使用 Microsoft.Jet.OLEDB.4.0 连接器访问文件,使用 SqlConnector 在 MS SQL 中写入数据,以提高性能我使用 SqlBulkCopy 方法。大多数文件都可以正常转换,但在某些方法上 SqlBulkCopy.WriteToServer 会引发异常:

记录被删除。 在任何记录中都找不到搜索键。

复制操作未完成,我在 SQL 中丢失了很多记录。

有没有办法绕过这个问题,还是我想放弃 SqlBulkCopy 并逐行复制?

编辑: 所以我决定打包数据库,但到目前为止还没有运气。当我使用 vfpoledb 进行阅读时,由于转换小数的问题,它会更快地崩溃。所以我想先使用 PACK(使用 vfpoledb),然后使用 JetOleDb 阅读器。即使执行了 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);
        }

谢谢

【问题讨论】:

  • 你可以尝试使用 sqlbulkcopy 对象的批量大小属性。

标签: c# sql sql-server dbf


【解决方案1】:

看起来有些记录被标记为已删除。如果您需要这些记录,请将它们恢复,如果不需要这些记录,则将它们永久删除(使用 PACK 命令)。

【讨论】:

  • 好的,所以我不需要这些记录,我尝试 PACK 数据库,但出现错误。您知道是否可以使用 Microsoft.Jet.OLEDB.4.0 运行 PACK?当我这样做时: var packCommand = new OleDbCommand(string.Format("PACK {0}", tableName), oleConnector); var 结果 = packCommand.ExecuteNonQuery();我得到了 OleDbException - 无效的 SQL 命令、DELETE、INSERT、PROCEDURE、SELECT 或 UPDATE 预期
  • 不确定 JetOLEDB。尝试指定文件名,例如“打包 some_file.dbf”
【解决方案2】:

所以经过一番挖掘,我得出了最终的解决方案,所以我将总结一下我的发现。 “记录被删除”异常非常具有误导性,因为问题实际上从来不是被删除的记录。有 3 个空行,实际上触发了异常。一旦这些被删除,一切都开始工作,我什至不必打包数据库。这适用于我使用 Microsoft.Jet.OLEDB 连接器的场景。

我尝试使用 vfpoledb 连接器,但遇到了十进制数的其他问题。我写了一个受this msdn discussion 启发的修复程序,不仅一切都开始工作(因此已成功跳过删除和空行),而且现在导入速度比使用 Jet 连接器快 15 倍(再次使用 BulkCopy)

【讨论】:

    猜你喜欢
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 2014-03-31
    • 1970-01-01
    • 2012-02-21
    • 2016-05-30
    • 2015-11-18
    相关资源
    最近更新 更多