【问题标题】:VB Net - SQL - Compare Values of textbox and SQL ValueVB Net - SQL - 比较文本框的值和 SQL 值
【发布时间】:2021-02-19 02:25:39
【问题描述】:

这是我的代码:

Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
    Try
        myCmd = myConn.CreateCommand
        myCmd.CommandType = CommandType.Text
        myCmd.CommandText = ("SELECT * FROM login WHERE username = '" + txtboxUser.Text + "'")
        myCmd.ExecuteNonQuery()
        myReader = myCmd.ExecuteReader(CommandBehavior.CloseConnection)
        While myReader.Read
            UserVerifier = myReader.GetString(0).ToString()
            PassVerifier = myReader.GetString(1).ToString()
        End While
    Catch ex As Exception
        ErrorDB()
    End Try
    If String.IsNullOrEmpty(UserVerifier) Then
        MessageBox.Show("Username does not exist", "Login Failed.")
        txtboxUser.Clear()
        txtboxPassword.Clear()
        txtboxUser.Select()
    Else
        If txtboxPassword.Text = PassVerifier Then
            MessageBox.Show("Welcome" + txtboxUser.Text + "!", "Login Success!")
            Me.Hide()
            Form1.Show()
        Else
            MessageBox.Show("Incorrect Password", "Login Failed.")
            txtboxPassword.Clear()
            txtboxPassword.Select()
        End If
    End If
End Sub

而且好像这行代码好像不行,总是不匹配:

If txtboxPassword.Text = PassVerifier Then
            MessageBox.Show("Welcome" + txtboxUser.Text + "!", "Login Success!")
            Me.Hide()
            Form1.Show()
        Else

我尝试了几种我研究过的解决方案,但似乎都没有奏效。也许我的代码中缺少一些东西?有人可以向我解释为什么“PassVerifier = myReader.GetString(1).ToString()”不返回字符串数据类型吗?那它会得到什么?如何将其转换为与 txtboxPassword.Text 相同?我真的很困惑,请帮助。非常感谢。

编辑:即使 txtboxPassword.Text 和 PassVerifier 的结果相同,为什么 If 语句“If txtboxPassword.Text = PassVerifier Then”不能工作?我在获取数据或转换数据方面缺少什么吗?它总是通过它并且总是在 Else 语句中产生结果。

【问题讨论】:

  • 鉴于,顾名思义,GetString 返回一个String,那么在结果上调用ToString 有什么意义?这并没有什么坏处,但它表明您实际上并没有考虑您的数据类型,这总会在某个时间导致问题。此外,如果要连接 Strings,请使用连接运算符 (&) 而不是加法运算符 (+)。他们在许多情况下做同样的事情,但不是全部。前者总是做正确的事,所以总是使用它,你就不会出错。
  • 至于问题,调试你的代码。您应该在此处发布之前完成此操作。如果这两个值始终在该行上匹配,则这两个值始终相同。你想让我们怎么做?您可以自行调试代码并查看数据的来源,以及代码的行为与预期不同的确切位置和方式。至少,您应该能够告诉我们这是在哪里以及如何进行的。如果来自您的数据库的数据不是您所期望的,那么要么您的数据库有误,要么您的查询有误。
  • 最后,您应该学习如何在 ADO.NET 中使用参数,因为您构建查询的方式存在各种各样的问题,尤其是安全性。
  • 问题已编辑!
  • @jmcilhinney tbh 我只是在按照我们的教授教我们做的事情做:/为很多错误道歉!

标签: sql-server vb.net


【解决方案1】:

将用户界面代码与数据库访问代码分开是个好主意。 UI 代码处理MessageBox 和控件等。数据库代码不显示MesageBoxes,甚至不知道控件。我将 Try/Catch 放在 UI 代码中,以便您可以将任何错误传达给用户。

您的数据库对象应在使用它们的方法中声明,以便它们可以正确关闭和处置。使用块声明和处置这些对象。将连接字符串传递给连接的构造函数,将命令文本和连接传递给命令的构造函数。

总是使用参数来避免sql注入等原因。我不得不猜测数据类型和字段大小。检查您的数据库中的正确值。

由于您只需要计数,因此没有理由拉下整个记录。由于我们只检索单个值,您可以使用 .ExecuteScalar。

Private ConStr As String = "Your connection string"

Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
    If txtboxUser.Text = "" OrElse txtboxPassword.Text = "" Then
        MessageBox.Show("please fill all boxes")
        Exit Sub
    End If
    Dim RetVal As Boolean
    Try
        RetVal = ValidateLogin(txtboxUser.Text, txtboxPassword.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
    If RetVal Then
        MessageBox.Show("Welcome" + txtboxUser.Text + "!", "Login Success!")
        Me.Hide()
        Form1.Show()
    Else
        MessageBox.Show("Login Failed.")
    End If
End Sub

Private Function ValidateLogin(User As String, Password As String) As Boolean
    Dim RetVal As Boolean
    Dim ReturnedCount As Integer
    Using cn As New SqlConnection(ConStr),
            cmd As New SqlCommand("Select Count(*) From [login] WHERE [username] = @Username AND [password] = @Password;", cn)
        cmd.Parameters.Add("@Username", SqlDbType.NVarChar, 100).Value = User
        cmd.Parameters.Add("@Password", SqlDbType.NVarChar, 100).Value = Password
        cn.Open()
        ReturnedCount = CInt(cmd.ExecuteScalar)
    End Using 'closes the connection, disposes the connection and command
    If ReturnedCount = 1 Then 'there is a matching record
        RetVal = True
    End If
    Return RetVal
End Function

当然,在实际应用中,您绝不将密码存储为纯文本。

【讨论】:

  • 我知道这晚了 3 天,但是,感谢您的解释!现在一切正常,对我来说一切都更清楚了。非常感谢你,上帝保佑:)))
【解决方案2】:

好的,您没有显示设置连接的位置和“cmd”变量。

这些不应该放任不管。

而且您没有在代码中显示您检查密码的位置。

我假设您在模块顶部完成了导入 system.data.SqlClient。

我假设您在项目“设置”中使用了 + 设置连接字符串。

所以,我们的代码将:

Check for user - if none tell user
Check for password - if none tell user

Check if user name exists - if not - tell user
Check if pasword match - if not - tell user.

因此代码将如下所示:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    If txtBoxUser.Text = "" Then
        MessageBox.Show("Please enter a user name", "No user name")
        Exit Sub
    End If

    If txtboxPassword.Text = "" Then
        MessageBox.Show("Please enter a password", "No password")
        Exit Sub
    End If

    Dim strSQL As String = "SELECT * FROM login "
    Dim MyTable As New DataTable

    Using cmdSQL As New SqlCommand("", New SqlConnection(My.Settings.TESTdb))

        cmdSQL.Connection.Open()

        cmdSQL.CommandText = strSQL & " WHERE username = @User"
        cmdSQL.Parameters.Add("@User", SqlDbType.NVarChar).Value = txtBoxUser.Text

        MyTable.Load(cmdSQL.ExecuteReader)

        If MyTable.Rows.Count = 0 Then
            MessageBox.Show("User name does not exist", "Logon Failed")
        Else
            ' name was ok - try name + password
            cmdSQL.CommandText = strSQL & " WHERE userName = @User AND Password = @Pass"
            cmdSQL.Parameters.Add("@Pass", SqlDbType.NVarChar).Value = txtboxPassword.Text
            MyTable.Clear()
            MyTable.Load(cmdSQL.ExecuteReader)
            If MyTable.Rows.Count = 0 Then
                MessageBox.Show("Password incorrect", "Password fail")
            End If
        End If

        ' get here without rows, then clear passwords info, or we are OK!!!
        If MyTable.Rows.Count = 0 Then
            txtBoxUser.Clear()
            txtboxPassword.Clear()
        Else
            MessageBox.Show("Welcome " & txtBoxUser.Text & "!", "Login Success!")
        End If

    End Using

End Sub

现在我们应该把它从按钮 sub 移到一个单独的“函数”中,并让这个例程根据成功或失败返回 true 或 false,但我会把这部分留给你(必须让你做一些事情在这里!)。

【讨论】:

  • 您正在显示带有打开连接的消息框。我认为连接应该是使用它的方法的本地连接。你为什么要告诉潜在的黑客登录的哪一部分是错误的?登录失败就足够了。为什么要两次访问数据库?当您只需要计数时,为什么要拉下整个记录?
猜你喜欢
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 2010-10-21
相关资源
最近更新 更多