C#將SQLite資料庫資料轉存(匯入)至Access資料庫中
阿新 • • 發佈:2020-10-12
因為專案上的一個小需求,需要將SQLite資料庫中的資料匯入到Access資料庫。最近兩天查了一些資料,用C# winform實現這個功能。本文記錄實現的流程。
開發環境(C# winform):
1. visual studio 2019
2. .net framework 4.7.2
3. SQLite資料庫(test.db)
4. access 2007資料庫(data.accdb)
5. SQLite資料表tn_member,表結構內容如下圖:
實現流程:
1. 連線SQLite資料庫,讀取表 tn_member 的表結構
有關讀取SQLite表結構,可以參考這篇文章“C#對SQLite資料表的操作(建立、刪除、查看錶結構)”,此處不再多說。
2. 根據 tn_member 表結構,生成對應的Access資料表結構,然後連線Access資料庫,建立 tn_member表
根據上一步讀取的SQLite表結構,讀取每個欄位的欄位名、欄位型別等資訊,生成對應的Access表結構sql語句,此處需要注意的是要對照好SQLite和Access的欄位型別即可,程式碼片段如下:
privateboolcreateAccessTableBySqliteTable(stringtableName) { //讀取sqlite資料表結構 SqliteHelpersqliteHelper=newSqliteHelper(this.sqliteFilename,this.sqlitePassword); DataTabletable=sqliteHelper.TableSchema(tableName); //拼接access建立表sql StringBuildersqlBuilder=newStringBuilder(); sqlBuilder.Append($"createtable{tableName}("); foreach(DataRowrintable.Rows) { sqlBuilder.Append($"{r["name"]}"); sqlBuilder.Append($""); switch(r["type"].ToString().ToLower()) { case"integer": sqlBuilder.Append($"Integer"); break; case"real": sqlBuilder.Append($"Double"); break; case"text": sqlBuilder.Append($"Text"); break; case"DATETIME": sqlBuilder.Append($"DateTime"); break; default: sqlBuilder.Append($"Text"); break; } sqlBuilder.Append($","); } sqlBuilder.Remove(sqlBuilder.Length-1,1); sqlBuilder.Append(")"); stringcreateSql=sqlBuilder.ToString(); try { stringconnStr=getAccessConnStr(this.accessFilename); OleDbConnectionoldDbConn=newOleDbConnection(connStr); oldDbConn.Open(); OleDbCommandcmd=newOleDbCommand(createSql,oldDbConn); cmd.ExecuteNonQuery(); cmd.Dispose(); oldDbConn.Close(); oldDbConn.Dispose(); } catch(Exceptionex) { MessageBox.Show(ex.Message,"提示"); returnfalse; } returntrue; }
3. 逐條讀取SQLite表資料,生成Access插入語句,將資料插入Access表中
建立好Access表結構後,插入資料就比較簡單。只需要逐條讀取SQLite表資料,再對照Access的資料型別,將值進行轉換,然後插入Access資料庫。程式碼片段如下:
///<summary> ///將SQLite的表資料轉存到access資料庫對應的表中 ///</summary> ///<paramname="in_table">sqlite表</param> ///<paramname="accessFileName">access資料庫檔名</param> ///<paramname="accessTableName">access資料庫表名</param> ///<paramname="accessPassword">access資料庫密碼</param> ///<returns></returns> privatebooltransSqliteData2AccdbTable(DataTablein_table,stringaccessFileName,stringaccessTableName,stringaccessPassword="") { stringconnStr=getAccessConnStr(accessFileName,accessPassword); using(OleDbConnectionoldDbConn=newOleDbConnection(connStr)) { oldDbConn.Open(); for(intn=0;n<in_table.Rows.Count;n++) { StringBuildersqlBuilder=newStringBuilder(); sqlBuilder.Append($"INSERTINTO{accessTableName}("); StringBuildercolBuilder=newStringBuilder(); StringBuildervalBuilder=newStringBuilder(); for(intm=0;m<in_table.Columns.Count;m++) { if(!string.IsNullOrEmpty(in_table.Rows[n][m].ToString())) { colBuilder.Append(in_table.Columns[m].ColumnName).Append(","); stringval=""; switch(in_table.Columns[m].DataType.ToString()) { case"System.Int64": case"System.Int32": case"System.Double": val=in_table.Rows[n][m].ToString(); break; case"System.DateTime": case"System.String": val="'"+in_table.Rows[n][m].ToString()+"'"; break; default: val="'"+in_table.Rows[n][m].ToString()+"'"; break; } valBuilder.Append(val).Append(","); } } colBuilder.Remove(colBuilder.Length-1,1); valBuilder.Remove(valBuilder.Length-1,1); sqlBuilder.Append(colBuilder.ToString()).Append(")VALUES("); sqlBuilder.Append(valBuilder.ToString()).Append(")"); OleDbCommandinst=newOleDbCommand(sqlBuilder.ToString(),oldDbConn); inst.ExecuteNonQuery(); } oldDbConn.Close(); } returntrue; }
因為要實現自動同步,因此本人的程式碼中又將每次讀取的id進行儲存,以便關閉程式後下次自動續傳。