当我尝试嵌套sql查询时,以下代码会出现以下错误。
已经有一个与此命令关联的打开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 Category_Desc=@cat", 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 User_Name=@username", 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 User_ID=@user", 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
答案 0 :(得分:2)
错误消息是自解释的:在一个连接上只能有一个数据读取器处于活动状态(请参阅documentation中的备注)。
你可以找到罪魁祸首,试图了解哪些未被处置的对象是以更干净(可读,优雅)的方式责备或重写你的代码。
下面是一个代码应该是什么样子的示例:
Dim catid As Integer
Dim userid As Integer
'getting category_id
Using cmd As New SqlCommand("SELECT * FROM [JobDetails].[Category] where Category_Desc=@cat", 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 User_Name=@username", 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 Category_Desc=@cat", con)
可以写成:
SqlCommand("SELECT Category_ID FROM [JobDetails].[Category] where Category_Desc=@cat", con)
如果您只使用一个值,则无需检索整行
使用上述解决方案,您甚至可以重写调用以将Category_ID
字段检索为:
'getting category_id
Using cmd As New SqlCommand("SELECT Category_ID FROM [JobDetails].[Category] where Category_Desc=@cat", con)
cmd.Parameters.AddWithValue("@cat", ddlCategory.SelectedValue)
catid = cmd.ExecuteScalar()
End Using
'end
的行为和限制的文档