每篇隨便都得有個背景吧,這次做一個項目時,突然碰到這個樣一個問題,需要將本地sqlserver中的數據導出到access后,再傳輸access數據庫,所以就在想怎樣實現這樣的操作。后面經過在網上查找了一些資料結合以前的知識,搞了這樣一個東西出來;
1 /// <summary> 2 /// 從sqlserver中導出數據到access 3 /// state=0 Jzjl 導出菜品信息表 4 /// state=1 lbxf_jz 導出收銀信息表 5 /// </summary> 6 /// <param name="host"></param> 7 /// <param name="name"></param> 8 /// <param name="password"></param> 9 /// <param name="root"></param> 10 static void BackupA(string tablename, int state, string connection = "Data Source=.;Initial Catalog=mpcy;Integrated Security=True") 11 { 12 string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 13 string file = "mpcy.model"; 14 string root = path + file; 15 16 Console.WriteLine("文件路徑:" + root); 17 //備份Access數據庫 18 if (state == 0) { tablename = "Jzjl"; chkandcrt(root); } else { tablename = "lbxf_jz"; } 19 20 root = BakPath + "\\mpcy.dat"; 21 string accesssqlconn = @"Provider=Microsoft.ACE.OLEDB.12.0;Jet OLEDB:DataBase Password=xhjxjf168;Data Source=" + root + ";"; 22 //SqlHelper.ConnectionString = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", "127.0.0.1", "mpcyTemp", "sa", "12345"); 23 //connection = string.Format("Data Source=.;Initial Catalog={0};Integrated Security=True", "mpcyTemp"); 24 SqlHelper.ConnectionString = connection; 25 //從sqlserver中讀出數據到datatable 26 OleDbConnection conn = new OleDbConnection(accesssqlconn); 27 OleDbCommand cmd = conn.CreateCommand(); 28 try 29 { 30 DataTable user = SqlHelper.ExecuteTable(CommandType.Text, string.Format("select * from {0}", tablename), null); 31 int i = 0; 32 if (user.Rows.Count > 0) 33 { 34 using (conn) 35 { 36 using (cmd) 37 { 38 conn.Open(); 39 40 //每次導入前,先清空數據庫表 41 string sql = string.Format("delete * from {0}", tablename); cmd.CommandText = sql; cmd.ExecuteNonQuery(); 42 43 OleDbDataAdapter adp = new OleDbDataAdapter(); adp.SelectCommand = new OleDbCommand(string.Format("select * from {0}", tablename), conn); OleDbCommandBuilder cb = new OleDbCommandBuilder(adp); DataSet data = new DataSet(); 44 //加載access中的數據表,並通過追加的方式放入dataset中 45 adp.Fill(data); 46 for (int j = 0; j < user.Rows.Count; j++) 47 { 48 //for (int l = 0; l < user.Columns.Count; l++) 49 //{ 50 // if (l > user.Columns.Count - 1) 51 // break; 52 DataRow dr = data.Tables[0].NewRow(); 53 for (int k = 0; k < dr.Table.Columns.Count; k++) 54 { 55 Type typ = user.Rows[j][k].GetType(); 56 if (typ == typeof(double) || typ == typeof(int) || typ == typeof(decimal) || typ == typeof(float)) 57 { if (string.IsNullOrEmpty(user.Rows[j][k].ToString())) { dr[k] = "0"; } else { dr[k] = user.Rows[j][k].ToString(); } } 58 else 59 { if (string.IsNullOrEmpty(user.Rows[j][k].ToString())) { dr[k] = " "; } else { dr[k] = user.Rows[j][k].ToString(); } } 60 } 61 //dr["UserID"] = user.Rows[j][l].ToString(); 62 //dr["UserName"] = user.Rows[j][l + 1].ToString(); 63 //網dataset中添加數據 64 data.Tables[0].Rows.Add(dr); 65 //} 66 } 67 data.Tables[0].TableName = tablename; 68 i = adp.Update(data.Tables[0]); //通過update方法Insert或update數據 69 Console.WriteLine(i.ToString()); 70 } 71 } 72 } 73 } 74 //判斷異常類型 75 catch (SqlException er) 76 { 77 ErrorTime++; 78 if (ErrorTime > 3) 79 { FileLog.Logger.Write(er); FileLog.Logger.Write("錯誤次數太多,退出程序!"); Console.WriteLine("錯誤次數太多,退出程序!"); } 80 else 81 { 82 if (ErrorTime % 2 == 0) 83 { 84 FileLog.Logger.Write("嘗試使用MSSQL身份驗證登陸數據庫!"); FileLog.Logger.Write(er); Console.WriteLine("SQLSERVER打開失敗,嘗試使用MSSQL方式登錄數據庫。"); 85 string sqlcon = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", ConfigHelper.DBHost, "mpcy", ConfigHelper.DBName, ConfigHelper.DBPwd); 86 //string sqlcon = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", "127.0.0.1", "mpcyTemp", "sa", "12345"); 87 BackupA("", state, sqlcon); 88 } 89 else 90 { FileLog.Logger.Write("嘗試使用WINDOWS身份驗證登陸數據庫!"); FileLog.Logger.Write(er); Console.WriteLine("SQLSERVER打開失敗,嘗試使用WINDOWS方式登錄數據庫。"); BackupA("", state); } 91 } 92 } 93 catch (Exception e) 94 { 95 FileLog.Logger.Write("數據導出失敗!"); FileLog.Logger.Write(e); Console.WriteLine("數據導出失敗!"); 96 //throw (new Exception("數據導出失敗,請聯系IT部!")); 97 } 98 finally 99 { 100 conn.Close(); 101 } 102 if (state == 0) 103 { 104 string sqlcon = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", ConfigHelper.DBHost, "mpcyTemp", ConfigHelper.DBName, ConfigHelper.DBPwd); 105 //string sqlcon = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", "127.0.0.1", "mpcyTemp", "sa", "12345"); 106 BackupA("", 1, sqlcon); 107 } 108 } 109 110 /// <summary> 111 /// 檢查並備份 112 /// </summary> 113 /// <param name="check"></param> 114 /// <param name="root"></param> 115 static void chkandcrt(string root) 116 { 117 try { if (!Directory.Exists(BakPath)) { Directory.CreateDirectory(BakPath); } if (!File.Exists(BakPath + "\\mpcy.dat")) { File.Copy(root, BakPath + "\\mpcy.dat"); } } 118 catch (Exception e) 119 { FileLog.Logger.Write(e); FileLog.Logger.Write("文件檢查失敗!"); Console.WriteLine("文件信息檢查失敗!"); } 120 }
代碼不多,核心代碼就這幾句:
OleDbDataAdapter adp = new OleDbDataAdapter(); adp.SelectCommand = new OleDbCommand(string.Format("select * from {0}", tablename), conn); OleDbCommandBuilder cb = new OleDbCommandBuilder(adp); DataSet data = new DataSet(); 44 //加載access中的數據表,並通過追加的方式放入dataset中 45 adp.Fill(data); 46 for (int j = 0; j < user.Rows.Count; j++) 47 { 48 //for (int l = 0; l < user.Columns.Count; l++) 49 //{ 50 // if (l > user.Columns.Count - 1) 51 // break; 52 DataRow dr = data.Tables[0].NewRow(); 53 for (int k = 0; k < dr.Table.Columns.Count; k++) 54 { 55 Type typ = user.Rows[j][k].GetType(); 56 if (typ == typeof(double) || typ == typeof(int) || typ == typeof(decimal) || typ == typeof(float)) 57 { if (string.IsNullOrEmpty(user.Rows[j][k].ToString())) { dr[k] = "0"; } else { dr[k] = user.Rows[j][k].ToString(); } } 58 else 59 { if (string.IsNullOrEmpty(user.Rows[j][k].ToString())) { dr[k] = " "; } else { dr[k] = user.Rows[j][k].ToString(); } } 60 } 61 //dr["UserID"] = user.Rows[j][l].ToString(); 62 //dr["UserName"] = user.Rows[j][l + 1].ToString(); 63 //網dataset中添加數據 64 data.Tables[0].Rows.Add(dr); 65 //} 66 } 67 data.Tables[0].TableName = tablename; 68 i = adp.Update(data.Tables[0]); //通過update方法Insert或update數據 69 Console.WriteLine(i.ToString());
這中間是這樣的:先通過一個DataAdapter讀取了Access數據庫的結構,然后再通過從Sqlserver中讀取到數據的DataTable將數據導入到這個被DataAdapter填充了結構的DataSet的表中。最后,通過這個DataAdapter來更新整個表,當然,表的結構要一致!!
另外,這里有一個OleDbCommandBuilder,根據網上解釋:自動生成用於協調對 DataSet的更改與關聯數據庫的單表命令。也就是說,在我們這個例子中,我們的表結構是沒有改變,但是后面新添加了數據,於是這個OleDbCommandBuilder就會自動將表單命令生成為Insert語句,於是就執行了插入命令,但是如果在我們初始化的DataSet中本來就存在數據,然后我們進行了對原始數據的改變,后面就會將命令變成Update。
這樣,就將Sqlserver中的數據填充到了Access數據庫中了。
參考:http://bbs.bccn.net/thread-292655-1-1.html
http://blog.csdn.net/a3676212/article/details/2776027
http://www.cnblogs.com/rhythmK/archive/2010/07/19/1780874.html