Intereting Posts
OledbConnection Close и / или Dispose очень медленные, занять 20 секунд для выполнения Длительное время загрузки в Visual Studio для большого проекта Поиск ElasticSearch с использованием клиента NEST C # Как зарегистрировать настраиваемое поле в NLog для базы данных? Как локально определяется в ToLocalTime () Выполнение процесса (с графическим интерфейсом) на экране входа в Windows XP (.NET / Pinvoke) Получить данные из одного текстового поля в form1 из другого текстового поля на form2 Как создать простой веб-сервер с помощью WCF без classа ServiceHost? Как получить изображение уже внутри RichEditBox в UWP На сегодняшний день, как правильно работать с COM-объектами? SemanticModel.GetTypeInfo () для ObjectCreationExpressionSyntax.Type возвращает null Предоставляет ли MEF какое-либо значение шаблону Singleton? Владелец windows «Устранение неполадок» в «Конструкторе родителя» Установить месяц отображения в элементе управления календарями WPF C Code Parser для .NET.

error ‘уже есть открытый datareader, связанный с этой командой, который должен быть закрыт первым’

runtime error ‘уже существует открытый datareader, связанный с этой командой, который должен быть закрыт первым’

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(); 

Здесь я не могу определить какую-либо хранимую процедуру. Любая помощь была бы оценена нами.

Как насчет того, чтобы вытащить данные в DataSet через Fill, а затем перебрать их, чтобы выполнить вставку через 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(); 

Не нужно делать все это, просто включите MARS, и ваша проблема будет решена. В вашей строке подключения просто добавьте MultipleActiveResultSets=True;

Вы не можете выполнить действие по этому соединению, пока оно все еще работает над чтением содержимого устройства чтения данных – ошибка довольно описательная.

Ваши альтернативы:

1) Сначала извлеките все свои данные, либо с помощью DataSet, либо используйте считыватель для заполнения какой-либо другой коллекции, а затем запустите их сразу после завершения первоначального выбора.

2) Используйте другое соединение для своих операторов вставки.

Лучше всего было бы прочитать нужную вам информацию в списке, а затем повторить список, чтобы выполнить ваши вставки так:

  List values = new List(); 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(); } } 
 INSERT INTO tablename (field1, field2) SELECT 3, field1 FROM sourcetable 

Единый оператор SQL вместо одного для каждой вставки. Не уверен, что это будет работать для вашей реальной проблемы, но для примера, который вы предоставили, это гораздо лучший вопрос, чем выполнение по одному за раз.

На стороне обратите внимание, что ваш код использует параметризованные запросы вместо того, чтобы принимать строки как есть внутри оператора SQL – ваш образец открыт для SQL-инъекции.

Было предложено несколько предложений, которые отлично работают, а также рекомендации по улучшению реализации. Я попал в лимит MARS из-за существующего кода, который не очищал читателя, поэтому я хотел собрать более респектабельный образец:

 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(); } } } 

Какую версию SQL Server вы используете? Проблема может заключаться в следующем:

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

Когда вы используете версии SQL Server до SQL Server 2005, в то время как SqlDataReader используется, связанный SqlConnection занят службой SqlDataReader. Хотя в этом состоянии никакие другие операции не могут выполняться в SqlConnection, кроме закрытия. Это происходит до тех пор, пока не вызывается метод Close для SqlDataReader.

Итак, если это то, что вызывает вашу проблему, вы должны сначала прочитать все данные, а затем закрыть SqlDataReader и только после этого выполнить свои вставки.

Что-то вроде:

 objCommand = new SqlCommand("SELECT field1, field2 FROM sourcetable", objConn); objDataReader = objCommand.ExecuteReader(); List values = new List(); 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(); } 

Добавление этого в строку подключения должно устранить проблему.

 MultipleActiveResultSets=true 

Вариант 1: необходимо выполнить запрос и загрузить данные перед запуском другого запроса.

Вариант 2: Добавить MultipleActiveResultSets=true для части поставщика вашей строки подключения. См. Пример ниже:

  

Попробуйте что-то вроде этого:

 //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(); } 

Лучшее решение. Существует только проблема с вашим значением «CommandText». Пусть это SP или обычный Sql Query.

  • Проверка 1: значение параметра, которое вы передаете в своем Sql Query, не меняется и не повторяется снова и снова в вашем ExecuteReader.

  • Проверка 2: Строка запроса Sql неверно сформирована.

  • Проверка 3: Пожалуйста, создайте простейший код следующим образом.

     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(); 

Для удобства использования я использую следующий шаблон кодирования:

 `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() }` в `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() }`