There is already an open DataReader associated with this Command which must be closed first.

I receivr the following error when executing this code:

There is already an open DataReader associated with this Command which must be closed first.

Code:

String sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + Server.MapPath("file.xlsx") + ";" +
            "Extended Properties=Excel 12.0";
        DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
       
        SqlConnection sqlConnectionString = new SqlConnection("Data Source=server;Initial Catalog=database;Persist Security Info=True;MultipleActiveResultSets=True;User ID=user;Password=password");
        sqlConnectionString.Open();
        SqlCommand cmd = new SqlCommand();

        try
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = sConnectionString;
                using (DbCommand command = connection.CreateCommand())
                {

                    command.CommandText = "SELECT [col1],[col2] FROM [Sheet1$]";
                    connection.Open();
                    using (DbDataReader dr = command.ExecuteReader())
                    {
                        int lineItems = 0;
                        while (dr.Read())
                        {
                            string strItemNum = dr["col1"].ToString().Trim();
                            string strPart = dr["col2"].ToString().Trim();
                            cmd.CommandText = "INSERT INTO table1 VALUES (@ProjectID, @VersionID)";
                            cmd.Parameters.Add("@ProjectID", SqlDbType.NVarChar);
                            cmd.Parameters["@ProjectID"].Value = ProjectDropDown.SelectedValue;
                            cmd.Parameters.Add("@VersionID", SqlDbType.NVarChar);
                            cmd.Parameters["@VersionID"].Value = Label3.Text;
                            cmd.CommandType = CommandType.Text;
                            cmd.Connection = sqlConnectionString;
                            cmd.ExecuteReader();
                        }
                        dr.Close();
                    }
                }
                connection.Close();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
        sqlConnectionString.Close();
LVL 15
melli111SharePoint Administrator / DeveloperAsked:
Who is Participating?
 
gavsmithConnect With a Mentor Commented:
Also you may want to use:

cmd.ExecuteNonQuery();

instead of:

cmd.ExecuteReader();

when it's a simple insert command
0
 
DhaestCommented:
Can you try the following
String sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + Server.MapPath("file.xlsx") + ";" +
            "Extended Properties=Excel 12.0";
        DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
        
        try
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = sConnectionString;
                using (DbCommand command = connection.CreateCommand())
                {

                    command.CommandText = "SELECT [col1],[col2] FROM [Sheet1$]";
                    connection.Open();
                    using (DbDataReader dr = command.ExecuteReader())
                    {
                        int lineItems = 0;
                        while (dr.Read())
                        {
                            string strItemNum = dr["col1"].ToString().Trim();
                            string strPart = dr["col2"].ToString().Trim();
                            cmd.CommandText = "INSERT INTO table1 VALUES (@ProjectID, @VersionID)";
                            cmd.Parameters.Add("@ProjectID", SqlDbType.NVarChar);
                            cmd.Parameters["@ProjectID"].Value = ProjectDropDown.SelectedValue;
                            cmd.Parameters.Add("@VersionID", SqlDbType.NVarChar);
                            cmd.Parameters["@VersionID"].Value = Label3.Text;
                            cmd.CommandType = CommandType.Text;
                            cmd.Connection = sqlConnectionString;
                            cmd.ExecuteReader();
                        }
                        dr.Close();
                    }
                }
                connection.Close();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }

Open in new window

0
 
gavsmithCommented:
Might be because you are repeatedly adding the connection to the command (you are also repeatedly adding parameters which will also make it fallover with parameter already exists) can you try this:

String sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + Server.MapPath("file.xlsx") + ";" +
            "Extended Properties=Excel 12.0";
        DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
        
        SqlConnection sqlConnectionString = new SqlConnection("Data Source=server;Initial Catalog=database;Persist Security Info=True;MultipleActiveResultSets=True;User ID=user;Password=password");
        sqlConnectionString.Open();
        SqlCommand cmd = new SqlCommand(sqlConnectionString);
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "INSERT INTO table1 VALUES (@ProjectID, @VersionID)";
        cmd.Parameters.Add("@ProjectID", SqlDbType.NVarChar);
        cmd.Parameters.Add("@VersionID", SqlDbType.NVarChar);

        try
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = sConnectionString;
                using (DbCommand command = connection.CreateCommand())
                {

                    command.CommandText = "SELECT [col1],[col2] FROM [Sheet1$]";
                    connection.Open();
                    using (DbDataReader dr = command.ExecuteReader())
                    {
                        int lineItems = 0;
                        while (dr.Read())
                        {
                            string strItemNum = dr["col1"].ToString().Trim();
                            string strPart = dr["col2"].ToString().Trim();
                            cmd.Parameters["@ProjectID"].Value = ProjectDropDown.SelectedValue;
                            cmd.Parameters["@VersionID"].Value = Label3.Text;
                            cmd.ExecuteNonQuery();
                        }
                        dr.Close();
                    }
                }
                connection.Close();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
        sqlConnectionString.Close(); 

Open in new window


Another tip is to check the state of a connection before you open/close it i.e.:

if (sqlConnectionString.State == ConnectionState.Closed)
  sqlConnectionString.Open();

Open in new window


in your case we know it won't be open because it has only just been created but good practise in other scenarios.

HTH
Gav
0
 
DhaestCommented:
Another remark: when you use the using-statement, you don't have to close your connection (this will be done)

http://www.hanselman.com/blog/WhyTheUsingStatementIsBetterThanASharpStickInTheEyeAndASqlConnectionRefactoringExample.aspx
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.