2012-01-11 46 views
5

我需要通過代碼修改MS Acess數據庫(.mdb)的模式。由於Jet Engine DDL語句(ALTER TABLE等)的記錄很差,我寧願使用某種類型的目標庫,如DAO(myDatabase.TableDefs("myTable").Fields.Append(myNewField))或ADOX(myCatalog.Tables("myTable").Columns.Append(myNewField))或SMO(它僅適用於對於SQL Server,語法類似 - 你有這個想法)。是否可以使用ADO.NET修改MS Access數據庫模式?

是否有類似ADOX的ADO.NET或我堅持使用DDL語句或引用舊的DAO/ADOX庫?

+1

你是什麼意思它是[不良記錄(http://msdn.microsoft.com/en-us/library/bb267262%28v=office.12%29.aspx)?哪種說法對你不清楚?無論如何,你可以在.NET中使用ADOX。例如,請參閱[如何使用ADOX和Visual C#.NET創建Access數據庫](http://support.microsoft.com/kb/317881)。 – RedFilter 2012-01-11 14:49:12

+0

感謝您的鏈接,它看起來像最新版本的Access中的文檔已大大改善。還有一個例子:ALTER TABLE頁面不包含有效數據類型的列表;例如,我將如何創建一個精度爲X,比例尺爲Y的新小數,這完全不清楚(在文檔中)。同時,我發現了這樣一個數據類型關鍵字表(它在用戶註釋部分中鏈接[CREATE TABLE文檔](http://msdn.microsoft.com/en-us/library/bb177893.aspx)),但這遠離SQL Server BOL的質量。 – Heinzi 2012-01-11 14:56:33

+2

哦,另一個爲什麼通過DDL管理Access架構不是一個好主意:[架構行集已損壞。](http://social.msdn.microsoft.com/Forums/eu/adodotnetdataproviders/thread/58a17c99-0b23 -4341-a274-db2dd91e0886)我剛剛瞭解到,OLE DB架構表和ODBC架構表都不會爲Access字段返回正確的IS_NULLABLE值。似乎只有*可靠的方法來檢查一個Access字段是否爲空是使用** DAO **並檢查'myField.Required'。那有多可悲?不得不在2012年爲.net項目添加DAO引用... – Heinzi 2012-01-12 14:47:54

回答

1

我已經有了直接ddl語句的體面的成功。你的權利語法需要一個谷歌搜索清除,但我一直在處理更新本地數據庫這種方式一段時間。是否有與您有問題的具體更新? 基本上我寫了一些幫助函數來檢查表的結構並在需要時附加字段。

public bool doesFieldExist(string table, string field) 
    { 
     bool ret = false; 
     try 
     { 
      if (!openRouteCon()) 
      { 
       throw new Exception("Could not open Route DB"); 
      } 
      DataTable tb = new DataTable(); 
      string sql = "select top 1 * from " + table; 
      OleDbDataAdapter da = new OleDbDataAdapter(sql, routedbcon); 
      da.Fill(tb); 
      if (tb.Columns.IndexOf(field) > -1) 
      { 
       ret = true; 
      } 

      tb.Dispose(); 


     } 
     catch (Exception ex) 
     { 
      log.Debug("Check for field:" + table + "." + field + ex.Message); 
     } 

     return ret; 
    } 


    public bool checkAndAddColumn(string t, string f, string typ, string def = null) 
    { 

     // Update RouteMeta if needed. 
     if (!doesFieldExist(t, f)) 
     { 
      string sql; 
      if (def == null) 
      { 
       sql = String.Format("ALTER TABLE {0} ADD COLUMN {1} {2} ", t, f, typ); 
      } 
      else 
      { 
       sql = String.Format("ALTER TABLE {0} ADD COLUMN {1} {2} DEFAULT {3} ", t, f, typ, def); 
      } 
      try 
      { 
       if (openRouteCon()) 
       { 
        OleDbCommand cmd = new OleDbCommand(sql, routedbcon); 
        cmd.ExecuteNonQuery(); 
        string msg = "Modified :" + t + " added col " + f; 
        log.Info(msg); 
        if (def != null) 
        { 
         try 
         { 
          cmd.CommandText = String.Format("update {0} set {1} = {2}", t, f, def); 
          cmd.ExecuteNonQuery(); 
         } 
         catch (Exception e) 
         { 
          log.Error("Could not update column to new default" + t + "-" + f + "-" + e.Message); 
         } 

        } 
        return true; 
       } 
      } 
      catch (Exception ex) 
      { 
       log.Error("Could not alter RouteDB:" + t + " adding col " + f + "-" + ex.Message); 
      } 

     } 
     else 
     { 
      return true; 

     } 
     return false; 
    }