1. 程式人生 > 實用技巧 >C#將SQLite資料庫資料轉存(匯入)至Access資料庫中

C#將SQLite資料庫資料轉存(匯入)至Access資料庫中

因為專案上的一個小需求,需要將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-200Q4111319116.png

實現流程:

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進行儲存,以便關閉程式後下次自動續傳。