2015-10-26 2 views
0

В следующем коде приведена следующая ошибка, когда я попытался вложить SQL-запросы.Вложение запросов sql в vb.net

Существует уже открытая DataReader, связанные с этой командой, которая должна быть закрыта первая

reader4 = cmd4.ExecuteReader()

Стек след:

[InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.] 
    System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5333807 
    System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +51 
    System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +155 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +82 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +53 
    System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +137 
    System.Data.SqlClient.SqlCommand.ExecuteReader() +99 
    CW_Recruiter_postjob.btnPostJob_Click(Object sender, EventArgs e) in C:\Users\Khav\Documents\Visual Studio 2013\WebSites\BSE14BFT_140928\CW\Recruiter\postjob.aspx.vb:42 
    System.EventHandler.Invoke(Object sender, EventArgs e) +0 
    System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9628722 
    System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +103 
    System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 
    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 
    System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724 

Код:

Protected Sub btnPostJob_Click(sender As Object, e As EventArgs) Handles btnPostJob.Click 
     Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("JPortalCS").ConnectionString) 
     con.Open() 
     Dim cmd As New SqlCommand("INSERT INTO [JobDetails].[Job](Job_Title,Job_Desc,Start_Date,End_Date,Status,Category_ID,Recruiter_ID) VALUES (@Title,@Desc,@Start,@End,@Status,@Category_ID,@Recruiter_ID)", con) 
     cmd.Parameters.AddWithValue("@Title", job_title.Text) 
     cmd.Parameters.AddWithValue("@Desc", job_desc.Text) 
     cmd.Parameters.AddWithValue("@Start", DateTime.Now.ToString("d")) 
     cmd.Parameters.AddWithValue("@End", DateTime.Now.ToString("d")) 
     cmd.Parameters.AddWithValue("@Status", "Available") 
     'getting category_id 
     Dim reader As SqlDataReader 
     Dim cmd2 As New SqlCommand("SELECT * FROM [JobDetails].[Category] where [email protected]", con) 
     cmd2.Parameters.AddWithValue("@cat", ddlCategory.SelectedValue) 
     reader = cmd2.ExecuteReader() 
     Dim catid As Integer 
     If reader.HasRows Then 
      reader.Read() 
      catid = reader.Item("Category_ID") 
     End If 
     'end 
     'getting user_id 
     Dim reader4 As SqlDataReader 
     Dim cmd4 As New SqlCommand("SELECT * FROM [UserDetails].[User] where [email protected]", con) 
     cmd4.Parameters.AddWithValue("@username", Session("login_user")) 
     reader4 = cmd4.ExecuteReader() 
     Dim userid As Integer 
     If reader4.HasRows Then 
      reader4.Read() 
      userid = reader4.Item("User_ID") 
     End If 
     'getting recruiter_id 
     Dim reader3 As SqlDataReader 
     Dim cmd3 As New SqlCommand("SELECT * FROM [UserDetails].[Recruiter] where [email protected]", con) 
     cmd3.Parameters.AddWithValue("@user", userid) 
     reader3 = cmd3.ExecuteReader() 
     Dim recruterid As String = "" 
     If reader3.HasRows Then 
      reader3.Read() 
      recruterid = reader3.Item("Recruiter_ID") 
     End If 
     'end 
     cmd.Parameters.AddWithValue("@Category_ID", catid) 
     cmd.Parameters.AddWithValue("@Recruiter_ID", recruterid) 
     cmd.CommandType = CommandType.Text 
     cmd.ExecuteNonQuery() 
     con.Close() 
    End Sub 
+1

Что линия в коде указал за исключением точно? –

+1

Вы должны реорганизовать свой код во что-то более структурированное, чтобы не поддерживать этот cmdX и readerX. Это также изолирует (возможно, даже автоматически исправляет) вашу проблему. Также вы действительно должны распоряжаться своими читателями. –

+0

Почему вы не используете инструкцию для использования? Https: //msdn.microsoft.com/en-us/library/htd05whh.aspx –

ответ

2

сообщение об ошибке самоочевидно: только один считыватель данных может быть активным в одном соединении (см. Примечания в documentation).
Вы можете охотиться за преступником, пытаясь понять, какой из многих объектов, которые не расположены, - это обвинять или переписывать ваш код более чистым (и читаемым, и элегантным) способом.

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

Dim catid As Integer 
Dim userid As Integer 
'getting category_id 
Using cmd As New SqlCommand("SELECT * FROM [JobDetails].[Category] where [email protected]", con) 
    cmd.Parameters.AddWithValue("@cat", ddlCategory.SelectedValue) 
    Using reader As SqlDataReader = cmd.ExecuteReader() 
     If reader.HasRows Then 
      reader.Read() 
      catid = reader.Item("Category_ID") 
     End If 
    End Using 
End Using 
'end 
'getting user_id 
Using cmd As New SqlCommand("SELECT * FROM [UserDetails].[User] where [email protected]", con) 
    cmd.Parameters.AddWithValue("@username", Session("login_user")) 
    Using reader As SqlDataReader = cmd.ExecuteReader() 
     If reader.HasRows Then 
      reader.Read() 
      userid = reader4.Item("User_ID") 
     End If 
    End Using 
End Using 

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

еще одно изменение, что может улучшить общую читаемость и стабильности является использование явного именования полей в запросе SQL:

SqlCommand("SELECT * FROM [JobDetails].[Category] where [email protected]", con) 

можно записать в виде:

SqlCommand("SELECT Category_ID FROM [JobDetails].[Category] where [email protected]", con) 

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

'getting category_id 
Using cmd As New SqlCommand("SELECT Category_ID FROM [JobDetails].[Category] where [email protected]", con) 
    cmd.Parameters.AddWithValue("@cat", ddlCategory.SelectedValue) 
    catid = cmd.ExecuteScalar() 
End Using 
'end 

взглянуть на документацию для поведения и пределов ExecuteScalar

Смежные вопросы