将数据插入Sql Compact

本文关键字:Compact Sql 插入 数据 | 更新日期: 2023-09-27 18:19:34

我有一个手持设备,它连接到Sql Server数据库,读取Sql服务器数据,并将其放在设备上的Sql Compact数据库上。这是我的代码:

public void InsertData() // Function insert data into SQL commapct database
{
    dt = new DataTable();
    dt = SqlServer_GetData_dt("Select id_price, price, id_item  from prices", SqlCeConnection); // get data form sql server
    if (dt.Rows.Count > 0)
    {
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            string sql = "";
            sql = "insert into prices" +
                " ( id_prices, price,id_item) values('"
                    + dt.Rows[i]["id_price"].ToString().Trim() + "', '"
                    + dt.Rows[i]["price"].ToString().Trim() + "', '"
                    + dt.Rows[i]["id_item"].ToString().Trim() + "')";
            obj.SqlCE_WriteData_bit(sql, connection.ConnectionString);//insert into sql compact
        }
    }

}
public DataTable SqlServer_GetData_dt(string query, string conn)
{
    try
    {
        DataTable dt = new DataTable();
        string SqlCeConnection = conn;
        SqlConnection sqlConnection = new SqlConnection(SqlCeConnection);
        sqlConnection.Open();
        {
            SqlDataReader darSQLServer;
            SqlCommand cmdCESQLServer = new SqlCommand();
            cmdCESQLServer.Connection = sqlConnection;
            cmdCESQLServer.CommandType = CommandType.Text;
            cmdCESQLServer.CommandText = query;
            darSQLServer = cmdCESQLServer.ExecuteReader();
            dt.Load(darSQLServer);
            sqlConnection.Close();
        }
        return dt;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        DataTable dt = new DataTable();
        return dt;
    }
}
public object SqlCE_WriteData_bit(string query, string conn)
{
    try
    {
        string SqlCeConnection = conn;
        SqlCeConnection sqlConnection = new SqlCeConnection(SqlCeConnection);
        if (sqlConnection.State == ConnectionState.Closed)
        {
            sqlConnection.Open();
        }
        SqlCeCommand cmdCESQLServer = new SqlCeCommand();
        cmdCESQLServer.Connection = sqlConnection;
        cmdCESQLServer.CommandType = CommandType.Text;
        cmdCESQLServer.CommandText = query;
        object i = cmdCESQLServer.ExecuteScalar();
        sqlConnection.Close();
        return i;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        return 0;
    }
}

这一切都很好,但问题是所有这些工作都很慢。我有20000行需要插入SQL紧凑型数据库。

有没有更快插入的方法?

谢谢。

将数据插入Sql Compact

除了每次调用的Connection使用率明显较差之外,您还可以通过完全消除查询处理器来大大改善情况。这意味着不要使用SQL。相反,使用TableDirectSqlCeResultset打开目标表。遍历源数据(DataTable是个坏主意,但那完全不同),并使用一系列CreateRecordSetValuesInsert

这里可以找到一个很好的例子(不过,我会再次使用SetValues来设置整行,而不是每个单独的字段)。

重用连接,不要为每个INSERT语句创建新连接。

不要将连接字符串传递给SqlCE_WriteData_bit方法,而是在InsertData方法中创建一次连接,然后将连接对象传递给SqlCE_WriteData_bit

将所有数据放入DataTable,然后使用SqlCeDataAdapter通过一次对Update的调用保存所有数据。为了获得最佳性能,您可能不得不摆弄UpdateBatchSize

仔细看,我发现你已经有了DataTable。因此,自己循环浏览它是荒谬的。请注意,正如您所拥有的,每个DataRowRowState都将是Unchanged,因此不会插入它们。我认为您可以调用DataTable.Load,使所有RowState值都保留为Added,但如果不是,则使用SqlDataAdapter,将AcceptChangesDuringFill设置为false并调用Fill

有没有更快插入的方法?

是的,但当我们谈论插入2万行时,它可能还不够"快"。

我看到的问题是,你正在为从SqlServer_GetData_dt检索的每一行打开一个连接,也就是说,你打开一个插入数据20k次的连接。。。打开连接是一项昂贵的交易。您应该使用StringBuilder对象构建整个查询,然后在一个批处理中执行所有插入语句。

这将带来一些性能提升,但不要指望它能解决您的问题,插入20k行仍然需要一些时间,特别是在需要重新构建索引的情况下。我的建议是,你应该彻底分析你的需求,并在如何处理它方面更聪明一点

  • 如果可能的话,捆绑一个预先填充的数据库,这样你的应用程序就不必受到填充过程性能的影响
  • 如果没有,请在后台运行insert进程,并仅在预填充完成时访问数据