C# 从MySQL到MS Access的1GB数据

C# 从MySQL到MS Access的1GB数据,c#,mysql,ms-access,odbc,oledb,C#,Mysql,Ms Access,Odbc,Oledb,情况:我正在创建一个自动任务,该任务通过ODBC查询MySQL,并使用OLEDB将结果集插入MS Access数据库(.mdb) 代码: OleDbConnection accCon = new OleDbConnection(); OdbcCommand mySQLCon = new OdbcCommand(); try { //connect to mysql Connect(); mySQLCon.Connection = conne

情况:我正在创建一个自动任务,该任务通过ODBC查询MySQL,并使用OLEDB将结果集插入MS Access数据库(.mdb)

代码:

OleDbConnection accCon = new OleDbConnection();
OdbcCommand mySQLCon = new OdbcCommand();
try
{
    //connect to mysql
    Connect();                
    mySQLCon.Connection = connection;              

    //connect to access
    accCon.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
        @"Data source= " + pathToAccess;
    accCon.Open();
    var cnt = 0;

    while (cnt < 5)
    {
        if (accCon.State == ConnectionState.Open)
            break;
        cnt++;
        System.Threading.Thread.Sleep(50);
    }

    if (cnt == 5)
    {
        ToolBox.logThis("Connection to Access DB did not open. Exit Process");
        return;
    }
} catch (Exception e)
{
    ToolBox.logThis("Faild to Open connections. msg -> " + e.Message + "\\n" + e.StackTrace);
}
OleDbCommand accCmn = new OleDbCommand();
accCmn.Connection = accCon;
//access insert query structure
var insertAccessQuery = "INSERT INTO {0} values({1});";
// key = > tbl name in access, value = > mysql query to b executed
foreach (var table in tblNQuery)
{
    try
    {
        mySQLCon.CommandText = table.Value;
        //executed mysql query                        
        using (var dataReader = mySQLCon.ExecuteReader())
        {
            //variable to hold row data
            var rowData = new object[dataReader.FieldCount];
            var parameters = "";
            //read the result set from mysql query
            while (dataReader.Read())
            {
                //fill rowData with the row values
                dataReader.GetValues(rowData);
                //build the parameters for insert query
                for (var i = 0; i < dataReader.FieldCount; i++)
                    parameters += "'" + rowData[i] + "',";

                parameters = parameters.TrimEnd(',');
                //insert to access
                accCmn.CommandText = string.Format(insertAccessQuery, table.Key, parameters);
                try
                {
                    accCmn.ExecuteNonQuery();
                }
                catch (Exception exc)
                {
                    ToolBox.logThis("Faild to insert to access db. msg -> " + exc.Message + "\\n\\tInsert query -> " + accCmn.CommandText );
                }                              
                parameters = "";
            }
        }
    }
    catch (Exception e)
    {
        ToolBox.logThis("Faild to populate access db. msg -> " + e.Message + "\\n" + e.StackTrace);
    }
}
Disconnect();
accCmn.Dispose();
accCon.Close();
OleDbConnection accCon=新的OleDbConnection();
OdbcCommand mySQLCon=新的OdbcCommand();
尝试
{
//连接到mysql
Connect();
mySQLCon.Connection=连接;
//连接到访问
accCon.ConnectionString=@“Provider=Microsoft.Jet.OLEDB.4.0;”+
@“数据源=”+路径访问;
accCon.Open();
var-cnt=0;
而(cnt<5)
{
if(accCon.State==ConnectionState.Open)
打破
cnt++;
系统.线程.线程.睡眠(50);
}
如果(cnt==5)
{
logThis(“访问数据库的连接未打开。退出进程”);
返回;
}
}捕获(例外e)
{
ToolBox.logThis(“未能打开连接。消息->”+e.Message+“\\n”+e.StackTrace);
}
OleDbCommand accCmn=新的OleDbCommand();
accCmn.Connection=accCon;
//access插入查询结构
var insertAccessQuery=“插入到{0}值({1});”;
//key=>tbl name在access中,value=>mysql查询到b已执行
foreach(tblNQuery中的var表)
{
尝试
{
mySQLCon.CommandText=table.Value;
//执行mysql查询
使用(var dataReader=mySQLCon.ExecuteReader())
{
//用于保存行数据的变量
var rowData=新对象[dataReader.FieldCount];
var参数=”;
//从mysql查询中读取结果集
while(dataReader.Read())
{
//用行值填充行数据
dataReader.GetValues(rowData);
//构建插入查询的参数
对于(变量i=0;i”+exc.Message+“\\n\\t插入查询->”+accCmn.CommandText);
}                              
参数=”;
}
}
}
捕获(例外e)
{
ToolBox.logThis(“未能填充access db.msg->”+e.Message+“\\n”+e.StackTrace);
}
}
断开连接();
accCmn.Dispose();
accCon.Close();
问题:

OleDbConnection accCon = new OleDbConnection();
OdbcCommand mySQLCon = new OdbcCommand();
try
{
    //connect to mysql
    Connect();                
    mySQLCon.Connection = connection;              

    //connect to access
    accCon.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
        @"Data source= " + pathToAccess;
    accCon.Open();
    var cnt = 0;

    while (cnt < 5)
    {
        if (accCon.State == ConnectionState.Open)
            break;
        cnt++;
        System.Threading.Thread.Sleep(50);
    }

    if (cnt == 5)
    {
        ToolBox.logThis("Connection to Access DB did not open. Exit Process");
        return;
    }
} catch (Exception e)
{
    ToolBox.logThis("Faild to Open connections. msg -> " + e.Message + "\\n" + e.StackTrace);
}
OleDbCommand accCmn = new OleDbCommand();
accCmn.Connection = accCon;
//access insert query structure
var insertAccessQuery = "INSERT INTO {0} values({1});";
// key = > tbl name in access, value = > mysql query to b executed
foreach (var table in tblNQuery)
{
    try
    {
        mySQLCon.CommandText = table.Value;
        //executed mysql query                        
        using (var dataReader = mySQLCon.ExecuteReader())
        {
            //variable to hold row data
            var rowData = new object[dataReader.FieldCount];
            var parameters = "";
            //read the result set from mysql query
            while (dataReader.Read())
            {
                //fill rowData with the row values
                dataReader.GetValues(rowData);
                //build the parameters for insert query
                for (var i = 0; i < dataReader.FieldCount; i++)
                    parameters += "'" + rowData[i] + "',";

                parameters = parameters.TrimEnd(',');
                //insert to access
                accCmn.CommandText = string.Format(insertAccessQuery, table.Key, parameters);
                try
                {
                    accCmn.ExecuteNonQuery();
                }
                catch (Exception exc)
                {
                    ToolBox.logThis("Faild to insert to access db. msg -> " + exc.Message + "\\n\\tInsert query -> " + accCmn.CommandText );
                }                              
                parameters = "";
            }
        }
    }
    catch (Exception e)
    {
        ToolBox.logThis("Faild to populate access db. msg -> " + e.Message + "\\n" + e.StackTrace);
    }
}
Disconnect();
accCmn.Dispose();
accCon.Close();
  • 内存使用率非常高(300MB++),而MS Access文件大小不会不断变化!看起来insert缓存了数据,而不是将其保存到磁盘

  • 非常慢!我知道我的查询在几秒钟内执行,但插入过程需要很长时间

  • 我曾尝试在MS Access中使用prepared语句,并将值作为参数插入,而不是字符串concat来创建插入查询。但是,我收到了以下异常消息:

    条件表达式中的数据类型不匹配


    有人知道如何解决这个问题或者有更好的方法吗

    您可以创建一个VBA宏,该宏使用该方法通过ODBC将数据拉入Access数据库。它可能会更快更简单

    要从外部程序或计划任务运行VBA代码,只需启动Access,使用/x命令行开关打开文件,它将在启动时运行导入宏。不过,GB的数据仍然需要一段时间。我找到了一个

    更好的选择是使用不同的数据库引擎后端,如免费版本的SQLServerExpress。这样你就有了更多的选择,而且它更加健壮。如果需要MS Access表单和报表,可以使用SQL Server创建ADP项目文件,也可以使用链接表获取数据。如果可以满足您的要求,您甚至可以不复制所有数据。

    为SQL server数据库创建DSN(数据源名称)。然后通过打开Microsoft Access数据库并选择从该DSN导入来选择该DSN。您应该能够导入精确的1GB表(模式、数据、所有内容)

    有关使用DSN的更多信息:


    或者,您可以使用该DSN链接到SQL server数据库(而不是导入到Access表),然后完全跳过导入。

    如果插入是事务的一部分。在事务中通常可以加快批量插入而不是编写代码,您可以求助于SQL Server Integration Services(SSI),并在午餐前完成。如果您的计算机上尚未安装SQL Server,则它可以作为


    使用SSIS,您可以创建可重用的SSIS包,该包可以从命令行或计划任务触发。显示如何将数据从MySQL拉入SQL Server,但SQL Server部分应该很容易操作。

    一些带有注释的更改,以添加用于命令执行的事务。如果不手动控制事务,则每次都会自动创建和提交事务,这是一项耗时的操作

                OleDbConnection accCon = new OleDbConnection();
                OdbcCommand mySQLCon = new OdbcCommand();
                try
                {
                    //connect to mysql
                    Connect();
                    mySQLCon.Connection = connection;
    
                    //connect to access
                    accCon.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
                                              @"Data source= " + pathToAccess;
                    accCon.Open();
                    var cnt = 0;
    
                    while (cnt < 5)
                    {
                        if (accCon.State == ConnectionState.Open)
                            break;
                        cnt++;
                        System.Threading.Thread.Sleep(50);
                    }
    
                    if (cnt == 5)
                    {
                        ToolBox.logThis("Connection to Access DB did not open. Exit Process");
                        return;
                    }
                }
                catch (Exception e)
                {
                    ToolBox.logThis("Faild to Open connections. msg -> " + e.Message + "\\n" + e.StackTrace);
                }
    //AMK: transaction starts here
                var transaction = accCon.BeginTransaction();
                OleDbCommand accCmn = new OleDbCommand();
    
                accCmn.Connection = accCon;
                accCmn.Transaction = transaction;
    //access insert query structure
                var insertAccessQuery = "INSERT INTO {0} values({1});";
    // key = > tbl name in access, value = > mysql query to b executed
                foreach (var table in tblNQuery)
                {
                    try
                    {
                        mySQLCon.CommandText = table.Value;
                        //executed mysql query                        
                        using (var dataReader = mySQLCon.ExecuteReader())
                        {
                            //variable to hold row data
                            var rowData = new object[dataReader.FieldCount];
                            var parameters = "";
                            //read the result set from mysql query
                            while (dataReader.Read())
                            {
                                //fill rowData with the row values
                                dataReader.GetValues(rowData);
                                //build the parameters for insert query
                                for (var i = 0; i < dataReader.FieldCount; i++)
                                    parameters += "'" + rowData[i] + "',";
    
                                parameters = parameters.TrimEnd(',');
                                //insert to access
                                accCmn.CommandText = string.Format(insertAccessQuery, table.Key, parameters);
                                try
                                {
                                    accCmn.ExecuteNonQuery();
                                }
                                catch (Exception exc)
                                {
                                    ToolBox.logThis("Faild to insert to access db. msg -> " + exc.Message +
                                                    "\\n\\tInsert query -> " + accCmn.CommandText);
                                }
                                parameters = "";
                            }
                        }
    //AMK: transaction commits here if every thing is going well
                        transaction.Commit();
                    }
                    catch (Exception e)
                    {
                        ToolBox.logThis("Faild to populate access db. msg -> " + e.Message + "\\n" + e.StackTrace);
    //AMK: transaction rollback here if there is a problem
                        transaction.Rollback();
                    }
                }
                Disconnect();
                accCmn.Dispose();
                accCon.Close();
    
    OleDbConnection accCon=新的OleDbConnection();
    OdbcCommand mySQLCon=新的OdbcCommand();
    尝试
    {
    //连接到mysql
    Connect();
    mySQLCon.Connection=连接;
    //连接到访问
    accCon.ConnectionString=@“Provider=Microsoft.Jet.OLEDB.4.0;”+
    @“数据源=”+路径访问;
    accCon.Open();
    var-cnt=0;
    而(cnt<5)