WithCoderWithCoderWithCoder

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的字段类型即可,代码片段如下:            

        private bool createAccessTableBySqliteTable(string tableName)
        {
            // 读取sqlite数据表结构
            SqliteHelper sqliteHelper = new SqliteHelper(this.sqliteFilename, this.sqlitePassword);
            DataTable table = sqliteHelper.TableSchema(tableName);
        
            // 拼接access创建表sql
            StringBuilder sqlBuilder = new StringBuilder();
            sqlBuilder.Append($"create table {tableName} (");
            foreach (DataRow r in table.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(")");
            string createSql = sqlBuilder.ToString();
            
            try
            {
                string connStr = getAccessConnStr(this.accessFilename);
                OleDbConnection oldDbConn = new OleDbConnection(connStr);
                oldDbConn.Open();
                OleDbCommand cmd = new OleDbCommand(createSql, oldDbConn);
                cmd.ExecuteNonQuery();
                cmd.Dispose();
                oldDbConn.Close();
                oldDbConn.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
                return false;
            }
            return true;
        }

        3. 逐条读取SQLite表数据,生成Access插入语句,将数据插入Access表中

            创建好Access表结构后,插入数据就比较简单。只需要逐条读取SQLite表数据,再对照Access的数据类型,将值进行转换,然后插入Access数据库。代码片段如下:

        /// <summary>
        /// 将SQLite的表数据转存到access数据库对应的表中
        /// </summary>
        /// <param name="in_table">sqlite表</param>
        /// <param name="accessFileName">access数据库文件名</param>
        /// <param name="accessTableName">access数据库表名</param>
        /// <param name="accessPassword">access数据库密码</param>
        /// <returns></returns>        
        private bool transSqliteData2AccdbTable(DataTable in_table, string accessFileName, string accessTableName, string accessPassword = "")
        {
            string connStr = getAccessConnStr(accessFileName, accessPassword);
            using (OleDbConnection oldDbConn = new OleDbConnection(connStr))
            {
                oldDbConn.Open();
                for (int n = 0; n < in_table.Rows.Count; n++)
                {
                    StringBuilder sqlBuilder = new StringBuilder();
                    sqlBuilder.Append($"INSERT INTO {accessTableName}(");

                    StringBuilder colBuilder = new StringBuilder();
                    StringBuilder valBuilder = new StringBuilder();
                    for (int m = 0; m < in_table.Columns.Count; m++)
                    {
                        if (!string.IsNullOrEmpty(in_table.Rows[n][m].ToString()))
                        {
                            colBuilder.Append(in_table.Columns[m].ColumnName).Append(",");

                            string val = "";
                            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(")");

                    OleDbCommand inst = new OleDbCommand(sqlBuilder.ToString(), oldDbConn);
                    inst.ExecuteNonQuery();
                }
                oldDbConn.Close();
            }

            return true;
        }

     因为要实现自动同步,因此本人的代码中又将每次读取的id进行保存,以便关闭程序后下次自动续传。

          


欢迎分享交流,转载请注明出处:WithCoder » C#将SQLite数据库数据转存(导入)至Access数据库中