截断大型dbf时出现未指定的错误

时间:2012-04-16 10:21:39

标签: oledb truncate dbf

我正在使用OleDbCommand来截断DBF文件。它适用于大多数文件,但如果文件大小是例如400 MB我收到“未指定的错误”。我在某处读过dbf文件的大小限制是2 GB,所以我希望有一种方法可以处理大文件......

System.Data.OleDb.OleDbException: Unspecified error
    at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
    at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
    at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
    at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
    at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
    at System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
    at OleDbTruncateTest.Program.Main(String[] args) in C:\Users\henjoh\Visual Studio 2008\Projects\OleDbTruncateTest\OleDbTruncateTest\Program.cs:line 22

以下是该操作的基本代码:

using System;
using System.Data.OleDb;
using System.IO;

namespace OleDbTruncateTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string file = @"C:\Temp\largefile.DBF";
                string pathName = Path.GetDirectoryName(file);
                string fileName = Path.GetFileName(file);

                using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + pathName + "; Extended Properties=dBase III"))
                {
                    connection.Open();
                    using (OleDbCommand comm = new OleDbCommand("DELETE FROM " + fileName, connection))
                    {
                        comm.ExecuteNonQuery();
                    }
                }
                Console.WriteLine("Done");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            Console.WriteLine("ENTER to exit...");
            Console.ReadLine();
        }
    }
}

关于如何截断大型dbf文件的任何想法?

1 个答案:

答案 0 :(得分:1)

使用.dbf文件,通常源自dBASE,Clipper和Foxpro(以及Visual FoxPro),它们都是32位设计,因此任何单个文件大小的上限为2 gig。别无选择,就是这样。如果文件超过2 gig文件限制,则它必须是.DBF文件,该文件由可以读取.dbf文件的其他产品处理,例如Sybase的Advantage Database Server,它可以直接读/写/支持.DBF文件和超出2 gig限制。

如果你想真正截断(即:删除所有记录),删除将仅标记要删除的记录并将记录留在那里直到你“填充”表。也就是说,因为我不使用Microsoft JET OleDB提供程序,而是使用Microsoft Visual FoxPro OleDbProvider download

然后,我将构建一个包含VFP命令的字符串,以显式打开该表并使用ZAP(删除所有记录和包并重建索引)......类似于

string VFPScript  = "ExecScript( "
      + "[USE " + fileName + " EXCLUSIVE] +chr(13)+chr(10) + "
      + "[IF USED( '" + fileName + "')] + chr(13)+chr(10) + "
         + "[ZAP] +chr(13)+chr(10)+ "
      + "[ENDIF] +chr(13)+chr(10)+ "
      + "[USE]  )";

// put this script into command object, then execute it...
using (OleDbCommand comm = new OleDbCommand( VFPScript, connection))
{
    comm.ExecuteNonQuery();
}

请注意。我不知道JET识别的唯一命令是“ExecScript()”函数,它在VFP中允许您将字符串作为命令块传递并执行它,就像它是.prg一样。所以你可以做循环和IF / ENDIF块之类的事情(有一些限制)。但是,此示例将字符串构建为

USE YourFile EXCLUSIVE
if used( "YourFile" )
   ZAP
ENDIF
USE

最后的说明。处理表名时。通过OleDB提供程序时,.DBF扩展名为IMPLIED,因此您不希望将.dbf扩展名用作字符串的一部分。两个OleDbProviders仍然会找到该表,只要它在连接字符串指向的路径中。

祝你好运。