【问题标题】:"Invalid attempt to read when no data is present"“不存在数据时尝试读取无效”
【发布时间】:2025-12-22 08:35:10
【问题描述】:

当没有数据存在 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

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

  • 我的 Dim SQL2 应该放在哪里?
  • @user2860150 - 同一个地方,不要更改检索数据的方式,只需使用While dbreader2.Read() 语法更改“读取”数据的方式。您将对dbreader 使用相同的概念,但在您发布的代码中有一个空的For 循环,所以我决定使用第二个阅读器(dbreader2)作为示例,因为它在循环中有逻辑。
  • 它说 SQL2 没有声明
  • @user2860150 - 你的代码中是否还有这行:Dim SQL2 = "select * from product where r_id = " &amp; requestid
  • 我已根据您建议的更改更新了我的代码。有任何想法吗? ://
【解决方案2】:

您调用第一个 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

【讨论】:

  • 当我使用此代码时,当我尝试在浏览器中打开时会出现白屏
  • 在调试器中检查您的 XML。我看不到您在哪里关闭 vendorproduct 节点,因此您的 XML 格式不正确。
【解决方案3】:

DataReader 用于从 SQL Server 数据库读取只进的行流。您需要调用读取下一条记录。

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

 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 中连接泄漏的主要原因之一。

你可以使用语句“使用”你做一个 try{} finally{} 块来做到这一点(这是同一件事)。

【讨论】: