2012-04-16 58 views
0

我正在使用OleDbCommand截斷DBF文件。它適用於大多數文件,但如果文件大小是例如400 MB我收到「未指定的錯誤」。我讀的地方,一個DBF文件的大小限制爲2 GB,所以我希望有一種方法具有文件大工作...截斷大型dbf時出現未指定的錯誤

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

使用.dbf文件(通常由dBASE,Clipper和Foxpro(以及Visual FoxPro)產生),它們都是32位設計的,因此對於任何單個文件大小而言都是2 G的上限。沒有選擇,就是這樣。如果該文件超過2 gig文件限制,則它必須是一個.DBF文件,該文件由可讀取.dbf文件的其他產品處理,例如可直接讀/寫/支持.DBF文件的Sybase Advantage Database Server和超出2倍的極限。

如果您想要真正截斷(即:刪除所有記錄),刪除將只標記要刪除的記錄並將記錄保留在那裏,直到您「包裝」表格爲止。這就是說,因爲我不使用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是否能夠識別的唯一命令是VFP中的「ExecScript()」函數,它允許您將字符串作爲一個命令塊傳遞並執行,就像它是.prg一樣。所以你可以做循環和IF/ENDIF塊之類的東西(有一些限制)。但是,此示例正在構建字符串爲

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

最後說明。處理表名時。當通過OleDB提供程序時,.DBF擴展名是IMPLIED,因此您不希望使用.dbf擴展名作爲字符串的一部分。只要它位於連接字符串指向的路徑中,OleDbProviders仍將找到該表。

祝你好運。

+0

感謝VFP OleDb Provider提示!它解決了截斷大型dbf文件的問題。不幸的是,它和OleDb Provider之間有太多其他的語法差異,只是爲了替換後者,所以我最終只使用VFP OleDb Provider來實現'delete from'命令。但它有效,所以我很高興! ;-) – Henrik 2012-04-17 05:58:33

+0

VFP OleDb Provider與此解決方案一起出現!我試圖達到完全相同的目的,非常感謝你。 – reno812 2013-04-17 15:17:23