• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1410
  • Last Modified:

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();
0
melli111
Asked:
melli111
  • 2
  • 2
1 Solution
 
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:
Also you may want to use:

cmd.ExecuteNonQuery();

instead of:

cmd.ExecuteReader();

when it's a simple insert command
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

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now