“无数据存在时读取无效”

时间:2013-12-16 18:27:15

标签: asp.net sql-server vb.net visual-studio

无数据存在时读取无效ASP.NET

  

错误在第46行:Dim requestid = dbreader.GetInt32(1)

我的数据库中该列的数据已经被卡住了。

如果需要,可以发布更多代码。

Imports System.Data.SqlClient

Public Class WebForm1
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    writemystuff()
End Sub

Dim conn As New SqlConnection

Sub CloseDatabase()
    conn.Close()
End Sub

Sub ConnectToDatabase()
    conn.ConnectionString = ConfigurationManager.ConnectionStrings("dbSQL").ConnectionString
    conn.Open()
End Sub


Sub writemystuff()

    'Response.Write(SQL1)

    Dim XMLOutput = "<?xml version=""1.0"" encoding=""utf-8"" ?>"
    'XMLOutput = XMLOutput + "<?xml-stylesheet type=""text/xsl"" href=""XMLSchema1.xslt""?>"
    XMLOutput = XMLOutput + "<requests "
    XMLOutput = XMLOutput + " xmlns = ""http://www.w3schools.com"""
    XMLOutput = XMLOutput + " xmlns:xsi = ""http://www.w3.org/2001/XMLSchema-instance"""
    XMLOutput = XMLOutput + " xsi:schemaLocation=""http://www.w3schools.com XMLSchema1.xsd"">"
    ConnectToDatabase()

    Dim choice = Request("requestchoice")
    Dim SQL1 = "select * from request where r_id = 314"
    If choice = "Request 112" Then
        SQL1 = "select * from request where r_id = 112"
    End If

    Dim cmd = New SqlCommand(SQL1, conn)
    Dim dbreader = cmd.ExecuteReader()
    For Each record In dbreader

    Next

    Dim requestid = dbreader.GetInt32(1)
    XMLOutput = XMLOutput + "<vendor"
    XMLOutput = XMLOutput + " v_name=""" & dbreader.GetString(2) & """"
    XMLOutput = XMLOutput + " v_id=""" & dbreader.GetInt32(0) & """"
    XMLOutput = XMLOutput + " r_id=""" & dbreader.GetInt32(1) & """"
    XMLOutput = XMLOutput + " >"
    Dim SQL2 = "select * from product where r_id = " & requestid

    Dim cmd2 = New SqlCommand(SQL2, conn)

    Dim dbreader2 = cmd2.ExecuteReader()
    For Each record2 In dbreader2
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"

    Next
    dbreader2.Close()
    XMLOutput = XMLOutput + "</request>"

    CloseDatabase()
    XMLOutput = XMLOutput + "</requests>"
    Response.Write(XMLOutput)
End Sub
End Class

更新了仍存在问题的代码:

Imports System.Data.SqlClient

Public Class WebForm1
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    writemystuff()
End Sub

Dim conn As New SqlConnection

Sub CloseDatabase()
    conn.Close()
End Sub

Sub ConnectToDatabase()
    conn.ConnectionString = ConfigurationManager.ConnectionStrings("dbSQL").ConnectionString
    conn.Open()
End Sub


Sub writemystuff()

    'Response.Write(SQL1)

    Dim XMLOutput = "<?xml version=""1.0"" encoding=""utf-8"" ?>"
    'XMLOutput = XMLOutput + "<?xml-stylesheet type=""text/xsl"" href=""XMLSchema1.xslt""?>"
    XMLOutput = XMLOutput + "<requests "
    XMLOutput = XMLOutput + " xmlns = ""http://www.w3schools.com"""
    XMLOutput = XMLOutput + " xmlns:xsi = ""http://www.w3.org/2001/XMLSchema-instance"""
    XMLOutput = XMLOutput + " xsi:schemaLocation=""http://www.w3schools.com XMLSchema1.xsd"">"
    ConnectToDatabase()

    Dim choice = Request("requestchoice")
    Dim SQL1 = "select * from request where r_id = 314"
    If choice = "Request 112" Then
        SQL1 = "select * from request where r_id = 112"
    End If

    Dim cmd = New SqlCommand(SQL1, conn)
    Dim dbreader = cmd.ExecuteReader()
    For Each record In dbreader


        While dbreader.Read()
            Dim requestid = dbreader.GetInt32(1)
            XMLOutput = XMLOutput + "<vendor"
            XMLOutput = XMLOutput + " v_name=""" & dbreader.GetString(2) & """"
            XMLOutput = XMLOutput + " v_id=""" & dbreader.GetInt32(0) & """"
            XMLOutput = XMLOutput + " r_id=""" & dbreader.GetInt32(1) & """"
            XMLOutput = XMLOutput + " >"
            Dim SQL2 = "select * from product where r_id = " & requestid
        End While

        Dim cmd2 = New SqlCommand(SQL2, conn)

        Dim dbreader2 = cmd2.ExecuteReader()
        While dbreader2.Read()
            XMLOutput = XMLOutput + "<product"
            XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
            XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
            XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
            XMLOutput = XMLOutput + " >"
        End While

    Next

    XMLOutput = XMLOutput + "</request>"


    CloseDatabase()
    XMLOutput = XMLOutput + "</requests>"
    Response.Write(XMLOutput)
End Sub
End Class

3 个答案:

答案 0 :(得分:2)

您需要在.Read()对象上调用SqlDataReader来获取该行的数据,如下所示:

While dbreader2.Read()
    ' Do logic here to get individual values from each row
End While 

更新:

而不是:

Dim dbreader2 = cmd2.ExecuteReader()
For Each record2 In dbreader2
    XMLOutput = XMLOutput + "<product"
    XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
    XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
    XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
    XMLOutput = XMLOutput + " >"

Next

这样做:

Dim dbreader2 = cmd2.ExecuteReader()
While dbreader2.Read()
    XMLOutput = XMLOutput + "<product"
    XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
    XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
    XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
    XMLOutput = XMLOutput + " >"
End While

  

注意:如果您有兴趣知道SqlDataReader是否有任何行,那么您可以在循环读取行之前检查它,如下所示:

Dim dbreader2 = cmd2.ExecuteReader()
If dbreader2.HasRows Then
    While dbreader2.Read()
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"
    End While
Else
    ' Potentially generate a "no data found" message here, etc.

End If

更新2:

好的,这是您的完整方法代码应该是什么样的:

Sub writemystuff()
    'Response.Write(SQL1)

    Dim XMLOutput = "<?xml version=""1.0"" encoding=""utf-8"" ?>"
    'XMLOutput = XMLOutput + "<?xml-stylesheet type=""text/xsl"" href=""XMLSchema1.xslt""?>"
    XMLOutput = XMLOutput + "<requests "
    XMLOutput = XMLOutput + " xmlns = ""http://www.w3schools.com"""
    XMLOutput = XMLOutput + " xmlns:xsi = ""http://www.w3.org/2001/XMLSchema-instance"""
    XMLOutput = XMLOutput + " xsi:schemaLocation=""http://www.w3schools.com XMLSchema1.xsd"">"
    ConnectToDatabase()

    Dim choice = Request("requestchoice")
    Dim SQL1 = "select * from request where r_id = 314"
    If choice = "Request 112" Then
        SQL1 = "select * from request where r_id = 112"
    End If

    Dim cmd = New SqlCommand(SQL1, conn)
    Dim dbreader = cmd.ExecuteReader()
    Dim requestid As Integer
    While dbreader.Read()
        requestid = dbreader.GetInt32(1)
        XMLOutput = XMLOutput + "<vendor"
        XMLOutput = XMLOutput + " v_name=""" & dbreader.GetString(2) & """"
        XMLOutput = XMLOutput + " v_id=""" & dbreader.GetInt32(0) & """"
        XMLOutput = XMLOutput + " r_id=""" & dbreader.GetInt32(1) & """"
        XMLOutput = XMLOutput + " >"
    End While

    Dim SQL2 = "select * from product where r_id = " & requestid
    Dim cmd2 = New SqlCommand(SQL2, conn)
    Dim dbreader2 = cmd2.ExecuteReader()
    While dbreader2.Read()
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"
    End While
    dbreader2.Close()
    XMLOutput = XMLOutput + "</request>"

    CloseDatabase()
    XMLOutput = XMLOutput + "</requests>"
    Response.Write(XMLOutput)
End Sub

答案 1 :(得分:1)

您过早地调用第一个DataReader的Next

For Each record In dbreader
   ' Do Nothing
Next

' Reader is now at the end - can't read any more!
Dim requestid = dbreader.GetInt32(1)

但实际上你应该使用Do While dbReader.Read()

Do While dbReader.Read()

    Dim requestid = dbreader.GetInt32(1)
    XMLOutput = XMLOutput + "<vendor"
    XMLOutput = XMLOutput + " v_name=""" & dbreader.GetString(2) & """"
    XMLOutput = XMLOutput + " v_id=""" & dbreader.GetInt32(0) & """"
    XMLOutput = XMLOutput + " r_id=""" & dbreader.GetInt32(1) & """"
    XMLOutput = XMLOutput + " >"

    Dim SQL2 = "select * from product where r_id = " & requestid

    Dim cmd2 = New SqlCommand(SQL2, conn)

    Dim dbreader2 = cmd2.ExecuteReader()
    Do While dbReader2.Read()
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"

    Loop
Loop

答案 2 :(得分:0)

DataReader用于从SQL Server数据库中读取仅向前行的行。您需要调用Read下一条记录。

在你的代码上,你需要改变它(例如,你需要改变它,因为它应该工作,请不要复制粘贴,请)

 Dim dbreader2 = cmd2.ExecuteReader()
    For Each record2 In dbreader2
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"

 Next

类似

 Dim dbreader2 = cmd2.ExecuteReader()
 While  dbreader2.Read()
        XMLOutput = XMLOutput + "<product"
        XMLOutput = XMLOutput + " p_name=""" & dbreader2.GetString(3) & """"
        XMLOutput = XMLOutput + " p_id=""" & dbreader2.GetInt32(0) & """"
        XMLOutput = XMLOutput + " cost=""" & dbreader2.GetDecimal(2) & """"
        XMLOutput = XMLOutput + " >"

 End While

正如您可能想象的那样,只要您使用数据读取器,您的连接仍然会很忙。您应始终确保可以关闭数据读取器以关闭连接并再次将其发送到池。这是.NET中连接泄漏的主要原因之一。

您可以使用“使用”语句执行此操作{} finally {}阻止(这是相同的事情)。