with visual true there recuperar primero open must multipleactiveresultsets mediante hay framework first este debe datos data conexion como closed cerrarlo cerrar associated asociado already abrir abierto c# ado.net

c# - visual - error ''ya hay un datareader abierto asociado con este comando que debe cerrarse primero''



sql data reader vb (12)

error de tiempo de ejecución ''ya hay un datareader abierto asociado con este comando que debe cerrarse primero''

objCommand = new SqlCommand("SELECT field1, field2 FROM sourcetable", objConn); objDataReader = objCommand.ExecuteReader(); while (objDataReader.Read()) { objInsertCommand = new SqlCommand("INSERT INTO tablename (field1, field2) VALUES (3, ''" + objDataReader[0] + "'')", objConn); objInsertCommand.ExecuteNonQuery();//Here is the error } objDataReader.Close();

No puedo definir ningún procedimiento almacenado aquí. Cualquier ayuda nos agradecería.


¿Qué hay de jalar los datos a un DataSet a través de Fill y luego iterar a través de eso para realizar su inserción a través de NonQuery?

IDbDataAdapter da; IDbCommand selectCommand = connection.CreateCommand(); selectCommand.CommandType = CommandType.Text; selectCommand.CommandText = "SELECT field1, field2 FROM sourcetable"; connection.Open(); DataSet selectResults= new DataSet(); da.Fill(selectResults); // get dataset selectCommand.Dispose(); IDbCommand insertCommand; foreach(DataRow row in selectResults.Tables[0].Rows) { insertCommand = connection.CreateCommand(); insertCommand.CommandType = CommandType.Text; insertCommand.CommandText = "INSERT INTO tablename (field1, field2) VALUES (3, ''" + row["columnName"].ToString() + "''"; } insertCommand.Dispose(); connection.Close();


¿Qué versión de SQL Server estás usando? El problema podría estar con esto:

(de http://msdn.microsoft.com/en-us/library/9kcbe65k.aspx )

Cuando usa versiones de SQL Server antes de SQL Server 2005, mientras se usa el SqlDataReader, la SqlConnection asociada está ocupada sirviendo al SqlDataReader. Mientras se encuentre en este estado, no se puede realizar ninguna otra operación en SqlConnection más que cerrarlo. Este es el caso hasta que se llama al método Close del SqlDataReader.

Entonces, si esto es lo que está causando su problema, primero debe leer todos los datos, luego cierre el SqlDataReader, y solo después de eso ejecute sus inserciones.

Algo como:

objCommand = new SqlCommand("SELECT field1, field2 FROM sourcetable", objConn); objDataReader = objCommand.ExecuteReader(); List<object> values = new List<object>(); while (objDataReader.Read()) { values.Add(objDataReader[0]); } objDataReader.Close(); foreach (object value in values) { objInsertCommand = new SqlCommand("INSERT INTO tablename (field1, field2) VALUES (3, ''" + value + "'')", objConn); objInsertCommand.ExecuteNonQuery(); }


Agregar esto a la cadena de conexión debería solucionar el problema.

MultipleActiveResultSets=true


Intenta algo como esto:

//Add a second connection based on the first one SqlConnection objConn2= new SqlConnection(objConn.connectionString)) SqlCommand objInsertCommand= new SqlCommand(); objInsertCommand.CommandType = CommandType.Text; objInsertCommand.Connection = objConn2; while (objDataReader.Read()) { objInsertCommand.CommandText = "INSERT INTO tablename (field1, field2) VALUES (3, ''" + objDataReader[0] + "'')"; objInsertCommand.ExecuteNonQuery(); }


La mejor solución: solo hay un problema con el valor "CommandText". Deja que sea SP o consulta normal de SQL.

  • Comprobación 1: el valor del parámetro que está pasando en su consulta Sql no está cambiando y va igual una y otra vez en su ExecuteReader.

  • Comprobación 2: la cadena de consulta Sql está formada incorrectamente.

  • Comprobación 3: Cree el código más simple de la siguiente manera.

    string ID = "C8CA7EE2"; string myQuery = "select * from ContactBase where contactid=" + "''" + ID + "''"; string connectionString = ConfigurationManager.ConnectionStrings["CRM_SQL_CONN_UAT"].ToString(); SqlConnection con = new SqlConnection(connectionString); con.Open(); SqlCommand cmd = new SqlCommand(myQuery, con); DataTable dt = new DataTable(); dt.Load(cmd.ExecuteReader()); con.Close();


Lo mejor sería leer la información que necesita en una lista y luego iterar la lista para realizar sus inserciones de la siguiente manera:

List<String> values = new List<String>(); using(SqlCommand objCommand = new SqlCommand("SELECT field1, field2 FROM sourcetable", objConn)) { using(SqlDataReader objDataReader = objCommand.ExecuteReader()) { while(objDataReader.Read()) { values.Add(objDataReader[0].ToString()); } } } foreach(String value in values) { using(SqlCommand objInsertCommand = new SqlCommand("INSERT INTO tablename (field1, field2) VALUES (3, ''" + value + "'')", objConn)) { objInsertCommand.ExecuteNonQuery(); } }


No hay necesidad de hacer todo eso, simplemente active MARS y su problema se resolverá. En su cadena de conexión, simplemente agregue MultipleActiveResultSets=True;


No puede realizar una acción en esa conexión mientras sigue trabajando en la lectura del contenido de un lector de datos; el error es bastante descriptivo.

Sus alternativas son:

1) Recupere todos sus datos primero, ya sea con un DataSet o use el lector para rellenar alguna otra colección, luego ejecútelos todos de una vez después de realizar la selección inicial.

2) Utilice una conexión diferente para sus declaraciones de inserción.


Para que se pueda desechar fácilmente, utilizo la siguiente plantilla de codificación:

`using (SqlConnection connection = new SqlConnection("your connection string")) { connection.Open(); using (SqlCommand cmd = connection.CreateCommand()) { cmd.CommandText = "Select * from SomeTable"; using (SqlDataReader reader = cmd.ExecuteReader()) { if(reader.HasRows) { while(reader.Read()){ // assuming that we''ve a 1-column(Id) table int id = int.Parse(reader[0].ToString()); } } } } connection.Close() }`


Se han dado varias sugerencias que funcionan muy bien, junto con recomendaciones para mejorar la implementación. Llegué al límite de MARS debido a que el código existente no limpiaba un lector, así que quería armar una muestra más respetable:

const string connectionString = @"server=./sqlexpress;database=adventureworkslt;integrated security=true"; const bool useMARS = false; using (var objConn = new System.Data.SqlClient.SqlConnection(connectionString + (useMARS ? ";MultipleActiveResultSets=True" : String.Empty))) using (var objInsertConn = useMARS ? null : new System.Data.SqlClient.SqlConnection(connectionString)) { objConn.Open(); if (objInsertConn != null) { objInsertConn.Open(); } using (var testCmd = new System.Data.SqlClient.SqlCommand()) { testCmd.Connection = objConn; testCmd.CommandText = @"if not exists(select 1 from information_schema.tables where table_name = ''sourcetable'') begin create table sourcetable (field1 int, field2 varchar(5)) insert into sourcetable values (1, ''one'') create table tablename (field1 int, field2 varchar(5)) end"; testCmd.ExecuteNonQuery(); } using (var objCommand = new System.Data.SqlClient.SqlCommand("SELECT field1, field2 FROM sourcetable", objConn)) using (var objDataReader = objCommand.ExecuteReader()) using (var objInsertCommand = new System.Data.SqlClient.SqlCommand("INSERT INTO tablename (field1, field2) VALUES (3, @field2)", objInsertConn ?? objConn)) { objInsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("field2", String.Empty)); while (objDataReader.Read()) { objInsertCommand.Parameters[0].Value = objDataReader[0]; objInsertCommand.ExecuteNonQuery(); } } }


Opción 1: debe ejecutar la consulta y cargar los datos antes de ejecutar otra consulta.

Opción 2: Agregue MultipleActiveResultSets=true a la parte del proveedor de su cadena de conexión. Vea el ejemplo a continuación:

<add name="DbContext" connectionString="Data Source=(LocalDb)/v11.0;Initial Catalog=dbName;Persist Security Info=True;User ID=userName;Password=password;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />


INSERT INTO tablename (field1, field2) SELECT 3, field1 FROM sourcetable

Una sola instrucción SQL en lugar de una por inserción. No estoy seguro de si esto funcionará para su problema de la vida real, pero para el ejemplo que proporcionó, esta es una consulta mucho mejor que hacerlas una por una.

En una nota al margen, asegúrese de que su código use consultas parametrizadas en lugar de aceptar cadenas tal como están dentro de la declaración de SQL; su muestra está abierta a la inyección de SQL.