0

Is there an other way to insert multiple objects to an MySQL database than the way shown here. This works but takes time to execute.

  using (MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connStr))
        {
            //Goes thrue the List<object>
            foreach(List<object> sub in listSubject)
            {
            MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand();
            cmd.Connection = conn;
            cmd.CommandText = "CALL stp_InsertSubject(@param_SubjectId, @param_ProjectId, @param_Used);";
            cmd.Parameters.AddWithValue("@param_SubjectId",Convert.ToInt32(sub[0]) );
            cmd.Parameters.AddWithValue("@param_ProjectId", Convert.ToInt32(sub[1]));
            cmd.Parameters.AddWithValue("@param_Used", Convert.ToBoolean(sub[2]) );

            conn.Open();

            cmd.ExecuteNonQuery();

            conn.Close();
                }

My Stored procedure:

CREATE DEFINER=`mortenstarck`@`%` PROCEDURE `stp_InsertSubject`(param_SubjectId int(45), param_ProjectId int(45), param_Used tinyint(1))

BEGIN INSERT INTO Subject_has_Projects(Subject_Id, Projects_Id, Used) VALUES (param_SubjectId, param_ProjectId, param_Used); END

mortenstarck
  • 2,713
  • 8
  • 43
  • 76

3 Answers3

2

Few things to improve:

  • Open the connection just one time outside the loop (no need to close with using)
  • Create the command, assign connection just one time before the loop
  • Create the parameters all before the loop with dummy values
  • Assign only the value inside the loop and call the ExecuteScalar()


using(MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connStr))
{  
    conn.Open(); 
    MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand();   
    cmd.Connection = conn;   
    cmd.CommandText = "CALL stp_InsertSubject(@param_SubjectId, @param_ProjectId, @param_Used);";  
    cmd.Parameters.AddWithValue("@param_SubjectId",0 );   
    cmd.Parameters.AddWithValue("@param_ProjectId", 0);   
    cmd.Parameters.AddWithValue("@param_Used", false );   
    foreach(List<object> sub in listSubject)   
    {   
        cmd.Parameters["@param_SubjectId"].Value = Convert.ToInt32(sub[0]) ;   
        cmd.Parameters["@param_ProjectId"].Value = Convert.ToInt32(sub[1]);   
        cmd.Parameters["@param_Used"].Value = Convert.ToBoolean(sub[2]);   
        Id = (Int64)cmd.ExecuteScalar();   
    }   
}   
Steve
  • 213,761
  • 22
  • 232
  • 286
1

You can try. Open connection outside foreach loop. This will save time in opening and closing connection every time in loop. This will improve performance.

Int64 Id = 0;
using (MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connStr))
{
    //Goes through the List<object>
    conn.Open();
    foreach(List<object> sub in listSubject)
    {
        MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "CALL stp_InsertSubject(@param_SubjectId, @param_ProjectId, @param_Used);";
        cmd.Parameters.AddWithValue("@param_SubjectId",Convert.ToInt32(sub[0]) );
        cmd.Parameters.AddWithValue("@param_ProjectId", Convert.ToInt32(sub[1]));
        cmd.Parameters.AddWithValue("@param_Used", Convert.ToBoolean(sub[2]) );
        Id = (Int64)cmd.ExecuteScalar();
    }
     conn.Close();
}

How bad is opening and closing a SQL connection for several times? What is the exact effect?

Community
  • 1
  • 1
Amit
  • 21,570
  • 27
  • 74
  • 94
0

Have you thought about surrounding these calls with a single transaction?

Rich
  • 2,076
  • 1
  • 15
  • 16