没有数据时读取失败

时间:2018-10-21 04:33:14

标签: vb.net sqldatareader

我有这个代码,它的工作(种类)。

Dim connString As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
    Dim conn As New SqlConnection(connString)
    conn.Open()
    Dim comm As New SqlCommand("SELECT username, Password,type   FROM users WHERE username='" & TextBox1.Text & "' AND Password='" & TextBox2.Text & "'", conn)
    Dim reader As SqlDataReader
    reader = comm.ExecuteReader

    Dim count As Integer
    count = 0
    While reader.Read
        count = count + 1
    End While
    If count = 1 Then
        MessageBox.Show("username and password are correct")


        Form2.Show()


        Form2.Label1.Text = Me.TextBox1.Text
        Form2.Label2.Text = reader(2).ToString
    ElseIf count > 1 Then
            MessageBox.Show("username and password are duplicated")
        Else
            MessageBox.Show("username and password are wrong")

    End If

此行出现错误:

Form2.Label2.Text = reader(2).ToString
and error is "Invalid attempt to read when no data is present"

为什么说“没有数据”

我所有数据都在数据库中吗?

有人可以帮助我更正此代码吗? 谢谢..

2 个答案:

答案 0 :(得分:1)

您根本不应该使用循环。您应该不可能获得多条记录,那么循环有什么用?您应该使用If语句,仅此而已:

If reader.Read() Then
    'There was a match and you can get the data from reader here.
Else
    'There was no match.
End If

如果可能有两个记录使用相同的用户名,则您的数据库设计和应用程序有问题。该列应该是唯一的,并且当有人尝试注册时,您的应用应该正在测试现有记录。

答案 1 :(得分:0)

SqlDataReader是仅转发数据读取元素。发生此错误是因为您两次调用阅读器的READ函数。一次为true递增到1,第二次为false退出while语句。由于您不再使用WHILE语句,因此读者必须已阅读结果集的末尾,因此没有可供您阅读的数据。

请考虑以下更改的代码:

Dim connString As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Dim count As Integer = 0 
Dim userType as string = ""

Using conn As New SqlConnection(connString)
    conn.Open()
    Using Comm as SqlCommand = conn.CreateCommand 
       comm.commandText = "SELECT username, Password, type FROM Users WHERE username = @UserName AND Password = @Pwd; "
       comm.parameters.AddWithValue("@Username", TextBox1.Text) 
       comm.parameters.AddWithValue("@Password", Textbox2.text) 

       Dim reader As SqlDataReader
       reader = comm.ExecuteReader

       If reader IsNot Nothing Then 
          If reader.HasRows() Then 
             While reader.read 
                count = count + 1 
                If Not reader.IsDbNull(2) Then userType = reader(2).ToString 
             End While 
          End If 
          If Not reader.IsClosed Then reader.close
          reader = Nothing 
       End If 
    End Using 
End Using
If count = 1 Then
    MessageBox.Show("username and password are correct")
    Form2.Show()

    Form2.Label1.Text = Me.TextBox1.Text
    Form2.Label2.Text = userType 
 ElseIf count > 1 Then
    MessageBox.Show("username and password are duplicated")
 Else
    MessageBox.Show("username and password are wrong")
 End If

首先,SQLParameters是您的朋友。学习他们。当使用SqlClient类时,它们是与SQL注入作斗争的最简单方法。

第二,请注意,我正在WHILE循环中实际从读取器中检索数据。这样可以确保有实际数据供我读取。

第三,注意SqlConnection和SqlCommand对象上的USING语句。这有助于垃圾回收,并且还有其他一些好处。

最后,在尝试访问SqlDataReader之前,请注意我正在执行的检查。如果您未返回任何结果,则类似的事情将防止出现另一个错误。