Link to home
Start Free TrialLog in
Avatar of melli111
melli111Flag for United States of America

asked on

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();
Avatar of Dirk Haest
Dirk Haest
Flag of Belgium image

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

ASKER CERTIFIED SOLUTION
Avatar of gavsmith
gavsmith
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
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