Как вернуть данные, относящиеся к 1 пользователю в базе данных SQL, с помощью VB.NET

Эта программа требует от пользователя выбрать номер своей карты из поля со списком, а затем ввести свой пароль. Если их пароль совпадает с паролем в базе данных, они входят в систему. Проблема в том, что мой код не выбирает одного конкретного пользователя, он берет только первого пользователя в базе данных, я не могу войти в систему любого другого пользователя, потому что я не Я не знаю, как написать код, который выбирает конкретного пользователя.

Вот что я написал до сих пор. Я думаю, проблема в функции RetrivAccountInformation(). Где-то там мне нужен код, указывающий, что он извлекает данные CardNumber, выбранные в поле со списком cboAccountNumbers. Любая помощь приветствуется.

Импортирует MySql.Данные

Импортирует MySql.Data.MySqlClient

Форма публичного класса1

Dim dbCon As MySqlConnection
Dim strQuery As String = ""
Dim SQLcmd As MySqlCommand
Dim DataReader As MySqlDataReader

Private m_strPass As String
Private m_decBalance As Decimal
Private m_strName As String
Private m_strUserPass As String
Private m_strCardNumber As String



Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btnLogin.Click

    'Assign users guessed password to variable
    m_strUserPass = txtPass.Text

    RetrieveAccountInformation() ' invoke 


    ' determine if PIN number is within valid range
    If m_strUserPass = m_strPass Then
        lblWelcome.Text = "Hi"


    Else

        ' indicate that incorrect password was provided
        lblWelcome.Text = "Sorry, Password the is incorrect." _
           & "Please re-enter the password ."

        ' clear user's previous PIN entry
        m_strUserPass = ""

    End If

    txtPass.Clear() ' clear TextBox

End Sub


' load application Form
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    'Prepare connection and query
    Try
        dbCon = New MySqlConnection("Server=localhost;Database=test;Uid=root;Pwd=mysql")

        strQuery = "SELECT CardNumber " &
                   "FROM Account"

        SQLcmd = New MySqlCommand(strQuery, dbCon)

        'Open the connection
        dbCon.Open()

        ' create database reader to read information from database
        DataReader = SQLcmd.ExecuteReader

        ' fill ComboBox with account numbers
        While DataReader.Read
            cboAccountNumbers.Items.Add(DataReader("CardNumber"))
        End While

        'Close the connection
        DataReader.Close()
        dbCon.Close()

    Catch ex As Exception
        'Output error message to user with explaination of error
        MsgBox("Failure to communicate" & vbCrLf & vbCrLf & ex.Message)


    End Try
End Sub


' invoke when user provides account number
Private Sub RetrieveAccountInformation()

    ' specify account number of record from which data
    ' will be retrieved
    dbCon = New MySqlConnection("Server=localhost;Database=***;Uid=***;Pwd=***")

    strQuery = "SELECT Password, Name, Balance " &
               "FROM Account"

    SQLcmd = New MySqlCommand(strQuery, dbCon)

    dbCon.Open() ' open database connection

    ' create database reader to read information from database
    DataReader = SQLcmd.ExecuteReader

    DataReader.Read() ' open data reader connection

    ' retrieve PIN number, balance amount and first name
    ' information from database
    m_strPass = Convert.ToString(DataReader("Password"))
    m_decBalance = Convert.ToDecimal(DataReader("Balance"))
    m_strName = Convert.ToString(DataReader("Name"))


    DataReader.Close() ' close data reader connection
    dbCon.Close() ' close database connection
End Sub ' RetrieveAccountInformation

Конец класса


person user3275784    schedule 05.02.2014    source источник
comment
Вам нужно добавить условие WHERE к вашему выборочному запросу   -  person Steve    schedule 05.02.2014


Ответы (1)


Вам нужно использовать предложение WHERE в своем операторе sql, чтобы получить информацию о конкретном пользователе.
Между прочим, просто использовать пароль в качестве ключа для получения вашей информации недостаточно (что блокирует двух пользователей, чтобы иметь один и тот же пароль ?) Итак, я полагаю, вы передаете в RetrieveAccountInformation как значение пароля, так и номер карты и используете эти значения для уникальной идентификации записи пользователя в учетной записи.

Private Function RetrieveAccountInformation(cardNum as String, pwd As String) As Boolean

    Dim result as Boolean
    strQuery = "SELECT Password, Name, Balance FROM Account " & _
               "WHERE Password = @pwd AND CardNumber=@card"

    Using dbCon = New MySqlConnection("Server=localhost;Database=***;Uid=***;Pwd=***")
    Using SQLcmd = New MySqlCommand(strQuery, dbCon)
        dbCon.Open() 
        SQLcmd.Parameters.AddWithValue("@pwd", pwd)
        SQLcmd.Parameters.AddWithValue("@card", cardNum)
        Using DataReader = SQLcmd.ExecuteReader

            if DataReader.Read() then
                m_strPass = Convert.ToString(DataReader("Password"))
                m_decBalance = Convert.ToDecimal(DataReader("Balance"))
                m_strName = Convert.ToString(DataReader("Name"))
                result = true
            else
                result = false
            End If
        End Using
    End Using
    End Using
End Function

Пересмотренная функция может быть вызвана с первого нажатия кнопки таким образом.

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
    Dim result As Boolean 
    if cboAccountNumbers.SelectedValue Is Nothing Then
         MessageBox.Show("Please select a Card Number")
    End If

    result = RetrieveAccountInformation(cboAccountNumbers.SelectedValue.ToString, txtPass.Text) 

    If result = True Then
        lblWelcome.Text = "Hi"
    Else
        ....

Я также изменил ваш Sub на логическую функцию, которая возвращает true, если вы нашли пользователя, или false, если нет. И последнее замечание: всегда помните, что передача пароля открытым текстом в команде базы данных не является хорошей практикой с точки зрения безопасности. Существует большой консенсус в отношении того, что наиболее безопасным способом является использование функции хэширования при сохранении пароля, а затем применение того же хэша к открытому тексту вашего пароля перед передачей значения по сети.

person Steve    schedule 05.02.2014
comment
Комментарий к понижению будет оценен. Это может помочь улучшить ответ - person Steve; 05.02.2014
comment
Нет, номер карты и пароль функции не передаются. Система предназначена для проверки того, соответствует ли введенный ими пароль паролю, связанному с CardNumber, который они выбрали в поле со списком. И что именно означают «@pwd» и «@card»? Я подумал, может быть, вы используете WHERE, чтобы перейти туда, где номер карты равен номеру, выбранному в поле со списком, но я не понимаю, как вы это пишете. - person user3275784; 05.02.2014
comment
Когда вы ищете пароль в базе данных, что произойдет, если у двух пользователей будет один и тот же пароль? Вы не можете быть уверены, что нашли пользователя с соответствующим номером карты. @xxx — это параметры. Этот метод более безопасен, чем объединение строк, потому что вы избегаете проблем с Sql Injection и синтаксическим анализом (что, если пароль содержит одинарную кавычку?) - person Steve; 05.02.2014
comment
Это краткий обзор внедрения Sql c -sharpcorner.com/uploadfile/puranindia/, и это ситуация, когда одна кавычка сеет хаос с запросом stackoverflow.com/questions/19326563/ - person Steve; 05.02.2014
comment
И это один из самых известных вопрос о Sql Injection здесь, на SO - person Steve; 05.02.2014
comment
Но CardNumber является первичным ключом, поэтому никакие два номера карт не могут быть одинаковыми. Имеет значение, если у 2 или более пользователей один и тот же пароль, потому что он связан только с 1 уникальным номером карты. По крайней мере, это то, что я пытаюсь сделать. Может я не правильно кодирую. Когда я набрал ваш код, я понял, что вы пытаетесь сделать, но откуда берутся cardNum и pwd в Dim cardNum as String, Dim pwd As String? - person user3275784; 05.02.2014
comment
В самом простом случае я бы подумал, что это будет что-то вроде этого strQuery = "SELECT Password, Name, Balance " & "FROM Account" & "WHERE CardNumber " = Val(cboAccountNumbers.Text) Но это неправильный синтаксис - person user3275784; 05.02.2014
comment
Я точно скопировал ваш код, и я все еще получаю ошибку. На этот раз под первым Dim в Dim cardNum as String, Dim pwd As String есть волнистая линия, говорящая, что спецификаторы действительны только в начале объявления, и когда я запускаю его, происходит сбой, когда я выбираю номер учетной записи, говоря, что ссылка на объект не установлена ​​​​на экземпляр объекта. ? - person user3275784; 06.02.2014
comment
Извините, моя вина, я написал код выше прямо в поле ответа. Ответ обновлен - person Steve; 06.02.2014
comment
На этот раз только одна ошибка: Пожалуйста, выберите номер карты. Итак, теперь я предполагаю, что проблема в том, что он не распознает, что номер карты был выбран? Я просто хочу сказать спасибо за вашу помощь с этим. Прошло больше года с тех пор, как я работал с VB, и это было с базами данных Access, а не с SQL. Так что спасибо за терпение к моему незнанию! - person user3275784; 06.02.2014
comment
Это действительно странно. cboAccountNumbers - это поле со списком, верно? и это приложение winform? SelectedItem должен иметь значение Nothing, только если вы ничего не выбираете или не вводите что-то, что не включено в список элементов, добавленных в комбо, в противном случае следует установить соответствующий текст элемента. - person Steve; 06.02.2014
comment
Я предлагаю опубликовать новый вопрос с обновленным кодом. Чтобы кто-то менее уставший, чем я, мог посмотреть и найти очевидную проблему. - person Steve; 06.02.2014
comment
В конце концов я разобрался с этим. Спасибо за вашу помощь! - person user3275784; 06.02.2014