2014-09-26 77 views
0

我的目標OLEDB自定義編碼

我需要創建一個特定格式的.dbf文件,由客戶指定。格式是的dBase III的.dbf與kamenicky編碼,使用整數,各種長度和雙列類型的特徵。

問題

我得到了幾乎所有的方式工作,只有一個障礙:那該死的編碼拒絕工作,儘管被寫入特定的轉換表,開關與兼容原來的字符的假名編碼。這意味着,輸出文件結束了,例如,用於將其指定爲進口串在A0的十六進制值炭FF的十六進制值。

如果你打算(-1)的問題,我將不勝感激的信息,爲什麼你在評論這樣做 - 甚至是「你不明白的問題,充分」將是很大的幫助我想知道在哪裏可以繼續我的研究(如,在非常基礎在這種情況下)

我都有種,排序的解決了這個問題(見註釋),但解決的辦法是有缺陷的,實際上並沒有回答給出的問題。

問題

我怎麼才能說服Jet.OLEDB提供商不亂用編碼?

有什麼我試圖

  • 使用FoxPro的供應商,這實際上工作得很好,除了小細節,我的客戶的軟件無法讀取產生的.dbf文件。

  • 通過字符集= XXX和我不一些其他的連接字符串修改插入數據,而無需使用OleDbParameter(所以輸入就不會得到正確轉義)無濟於事

  • 設置了幾個不同的編碼方式現在可以完全記得,每次A0的輸出結果都是FF。

  • 我發現一個AutoTranslate屬性over here,但據我可以告訴它只適用於SQL連接,因爲Jet.OLEDB不斷給我一個ISAM錯誤。

  • 我試圖玩弄周圍globalization settings,並沒有太大的幫助。

某些代碼

連接字符串:

"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=\"dBase III;\""; 

然後數據被使用的OleDbCommand插入,以填充有OleDbParameter類和構造的插入串中的單個細胞。可能是完全無用的,但這裏的代碼:

private void insertRows(T[] data, OleDbConnection connection) 
{ 
    using (OleDbCommand command = connection.CreateCommand()) 
    { 
     for (int i = 0; i < data.Count(); i++) 
     { 
      constructParams(data[i], i, command); 
      command.CommandText = constructInsert(i, _fileName); 

      command.ExecuteNonQuery(); 
     } 
    } 
} 

private void constructParams(T data, int index, OleDbCommand command) 
{ 
    command.Parameters.Clear(); 
    foreach (PropertyInfo prop in _props) 
    { 
     if(_cols.ContainsKey(prop.Name)) 
     { 
      command.Parameters.Add(new OleDbParameter("@" + prop.Name + index, prop.GetValue(data))); 
     } 
    } 
} 

private string constructInsert(int dataNum, string tableName) 
{ 
    string insert = "INSERT INTO [" + tableName + "] ("; 
    foreach(string key in _cols.Keys) 
    { 
     insert += "[" + key + "],"; 
    } 
    insert = insert.Remove(insert.Length - 1); 
    insert += ") VALUES"; 

    insert += " ("; 
    foreach (string key in _cols.Keys) 
    { 
     insert += "@" + key + dataNum + ","; 
    } 

    insert = insert.Remove(insert.Length - 1); 
    insert += ");"; 

    return insert; 
} 
+0

我已經解決了這個問題,儘管解決方案遠非完美。無論Jet.OLEDB使用什麼編碼,似乎都是(至少對於那些重要的字符)8位字符集,以及假身份編碼。因此,在OLEDB提供者完成寫入文件之後,我再次以其字節表示方式打開它,並手動替換字符,以便它們遵守假名編碼。當然,這不是對原始問題的回答 - 只是我不得不轉向絕望的解決方案。 – Fenixp 2014-09-29 13:02:46

回答

2

下面是一個簡單的東西我想,似乎有特殊的Unicode字符和代碼頁895的正確識別工作,當你想一起工作。這確實使用了Microsoft的VFP OleDb提供程序。但是,我有四個部分。

  1. 通過顯式代碼頁參考創建表,通常導致VFP可讀格式。

  2. 爲了保持向後兼容性至於你提到你的dBASE需要,使用COPY TO命令將VFP版本表頭轉換爲較舊的(也應該)的dBASE識別的格式

  3. 簡單的插入到的dBASE版本表(也是代碼頁895)

  4. 檢索所有記錄並查看Unicode結果。

// Connection to your data path, but explicitly referencing codepage 895 in connection string 
string connectionString = @"Provider=VFPOLEDB.1;Data Source=c:\\YourDataPath\\SomeSubFolder;CODEPAGE=895;"; 
string ans = ""; 

using (OleDbConnection connection = new OleDbConnection(connectionString)) 
{ 
    // create table syntax for a free table (not part of a database) that is codepage 895. 
    string cmd = "create table MyTest1 free codepage=895 (oneColumn c(10))"; 
    OleDbCommand command = new OleDbCommand(cmd, connection); 

    connection.Open(); 
    command.ExecuteNonQuery(); 

    // Now, create a script to use the MyTest1 table and create MyTest2 which 
    // SHOULD BE recognized in dBASE format. 
    string vfpScript = @"use MyTest1 
      Copy to MyTest2 type foxplus"; 


    command.CommandType = CommandType.StoredProcedure; 
    command.CommandText = "ExecScript"; 
    command.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript; 
    command.ExecuteNonQuery(); 

    // Simple insert into the 2nd instance of the table  
    command = new OleDbCommand("insert into Mytest2 (oneColumn) values (?)", connection); 
    command.Parameters.AddWithValue("parmForColumn", "çšjír_Þ‰"); 
    command.ExecuteNonQuery(); 

    // Now, get the data back. 
    command = new OleDbCommand("select * from Mytest2", connection); 
    OleDbDataAdapter da = new OleDbDataAdapter(command); 
    DataTable oTbl = new DataTable(); 
    da.Fill(oTbl); 

    if (oTbl.Rows.Count != 0) 
     // we should have one row, so get the string from the column 
     // and it SHOULD loo like the Unicode sample I inserted above. 
     ans = (string)oTbl.Rows[0]["oneColumn"]; 
} 

很明顯,你必須代碼通過所有列,並設置適用的參數週期,所以我離開這個給你。

+0

我已經在昨天的測試原始問題下發送了我在評論中提出的解決方案,似乎工作正常。可悲的是,我現在沒有時間正確地實施/測試您的解決方案 - 如果我將來有時間,我可能會回過頭來看看,我會告訴您它是否有效。無論如何,雖然未經測試,但我沒有看到爲什麼它不起作用的任何理由,所以我會給你賞金/答案(至少在未經測試的情況下)。感謝你的付出。 – Fenixp 2014-09-30 18:27:41