0

I want to insert more than 5 lac records in SQL Server CE in Windows Mobile 6.1

The code I am using is taking about 8 rows per second. which is just unbearable.

My code is as follows - I have DataTable with about 5 lac records:

     SqlCeCommand cmd1;
        for (int i = 0; i < table.Rows.Count; i++)
        {
            cmd1 = new SqlCeCommand("Insert into Master values('" + table.Rows[i].ItemArray[0].ToString() + "')", con);
            con.Open();
            cmd1.ExecuteNonQuery();
            con.Close();
        }

Please suggest alternatives (preferably bulk insert) that are faster.

Gorgsenegger
  • 7,356
  • 4
  • 51
  • 89

3 Answers3

0

Since you are not using SqlCommand for adding parameters safely as you should:

SqlCeCommand command = conn.CreateCommand();
command.CommandText = "INSERT INTO Master (MasterValue) VALUES (@masterValue)";
SqlCeParameter param = null;
param = new SqlCeParameter("@masterValue", SqlDbType.Text);
command.Parameters.Add(param); 
command.Parameters["@masterValue"].Value = table.Rows[i].ItemArray[0].ToString();

You can just go with string concatenation and build a long string containing all the inserts (this is not a very clean way of doing it, but if you know your data and there's no problem doing the inserts unsafe, then this could be an option)

string insert = string.Empty;
for(int i = 0; i < table.rows.Count; i++)
{
    insert += "Insert into Master values('" + table.Rows[i].ItemArray[0].ToString() + "');";
    if(i % 1000 == 0 || i+1 == table.rows.Count)
    {
        using (SqlCommand cmd1 = new SqlCommand(insert, con))
        {
            con.Open();
            cmd1.ExecuteNonQuery();
            con.Close();
            insert = string.Empty;
        }
    }   
}

Note that there is a semicolon at the end of each insert, and this is needed to run the inserts separately. Adjust the modulus to the number of inserts you want to do at a time.

Binke
  • 897
  • 8
  • 25
  • ADO .NET Connection Pooling is good but you could save yourself the `Open` and `Close` calls, as well `Dispose`ing the `SqlCeCommand`. – ta.speot.is Nov 08 '13 at 12:22
0

Use SqlCeResultSet.Insert with a SqlCeUpdatableRecord. This answer demonstrates the process.

Community
  • 1
  • 1
ta.speot.is
  • 26,914
  • 8
  • 68
  • 96
0

Instead of open/close the db for every entry, open before and after the sqlCommand:

CHANGE that

     SqlCeCommand cmd1;
    for (int i = 0; i < table.Rows.Count; i++)
    {
        cmd1 = new SqlCeCommand("Insert into Master values('" + table.Rows[i].ItemArray[0].ToString() + "')", con);
        con.Open();
        cmd1.ExecuteNonQuery();
        con.Close();
    }

TO

 SqlCeCommand cmd1 = new SqlCeCommand();
 con.Open();
 cmd1.Connection = con;
 for (int i = 0; i < table.Rows.Count; i++)
 {
     cmd1.CommandText = "Insert into Master values('" + table.Rows[i].ItemArray[0].ToString() + "')";
     cmd1.ExecuteNonQuery();
 }
 con.Close();

There may be faster techniques, for example using a parameterized query or a transaction that encapsulates all inserts and is committed at end.

 con.Open();
 SqlCeTransaction tx = conn.BeginTransaction();
 SqlCeCommand cmd1 = con.CreateCommand();
 cmd1.Transaction = tx;
 for (int i = 0; i < table.Rows.Count; i++)
 {
     cmd1.CommandText = "Insert into Master values('" + table.Rows[i].ItemArray[0].ToString() + "')";
     cmd1.ExecuteNonQuery();
 }
 tx.Commit();
 con.Close();

(untested code according to: http://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlcecommand.transaction%28v=vs.100%29.aspx)

josef
  • 5,951
  • 1
  • 13
  • 24