Shadyjunior
Shadyjunior

Reputation: 457

vb.net connection to access database

I am trying to migrate my Access db to a vb.net winform (.net framework). My exposure with this software is extremely limited and thus I am tackling each thing in part. My aim is to eventually convert the data to a SQL server before anyone does interject about using and access database (One thing at a time). Anyway I have connected by datasource, created a basic login form and have refactored the code I ported from my access database. This is what I have...

Public intLogonAttempts As Long
    Dim connection As New OleDbConnection(My.Settings.DataConnectionString)

    Private Sub Btn_Login_Click(sender As Object, e As EventArgs) Handles Btn_Login.Click



        Dim RetVal As Integer

        ' Check all information required has been inputted
        If Txt_Username.Text = "" Then
            MsgBox("Please enter a username.", vbOKOnly, "Required Data")
            Txt_Username.Select()
            Exit Sub
        End If

        If Txt_Password.Text = "" Then
            MsgBox("Please enter a password.", vbOKOnly, "Required Data")
            Txt_Password.Select()
            Exit Sub
        End If

        'If connection.State = ConnectionState.Closed Then
        '    connection.Open()
        'End If

        Dim cmd As New OleDbCommand("SELECT * FROM User where [username] = ? AND [Password] = ?", connection)
        cmd.Parameters.AddWithValue("@p1", Txt_Username.Text)
        cmd.Parameters.AddWithValue("@p1", Txt_Password.Text)
        connection.Open()
        RetVal = CInt(cmd.ExecuteScalar())

        If (RetVal = 1) Then
            ' Login successful
            MsgBox("Successful login")

            My.Settings.savedUsername = Txt_Username.Text
            My.Settings.savedPassword = Txt_Password.Text
            My.Settings.Save()
        Else
            ' Login unsuccessful
            intLogonAttempts = intLogonAttempts + 1

            If intLogonAttempts >= 3 Then
                MsgBox("You do not have access to this database. Please contact admin.", vbCritical, "Restricted Access!")
                Application.Exit()
                Exit Sub
            Else
                MsgBox("Password Invalid. Please Try Again", vbOKOnly, "Invalid Entry!")
                Txt_Password.Select()
            End If
        End If
    End Sub

However when my code hits "RetVal = CInt(cmd.ExecuteScalar())" the following error is returned;

System.Data.OleDb.OleDbException: 'Syntax error in FROM clause.'

What am I getting wrong here? I thought it was due to the sql statement but I am pretty sure that I have this correct?

Upvotes: 1

Views: 939

Answers (2)

Mary
Mary

Reputation: 15091

I have divided the code into separate methods to make each method doing only a single job.

The GetUserCount method is completely disconnected from the user interface. A user could be logging in from the web or a phone app and the same method could be used.

Use Using...End Using blocks for your database objects. This ensures that they are closed and disposed even if there is an error. I don't think you ever closed your connection.

Notice that the Select command is getting Count(*). In your code you are just getting * so, with .ExecuteScalar you would get the first column of the first row of your result set. Not what you need.

I used parameter names just for readability so, we can see that the parameters are added to the parameters collection in the same order that they are appear in the Select statement.

Use the .Add method for parameters. See http://www.dbdelta.com/addwithvalue-is-evil/ and https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ and another one: https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications Here is another https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html I had to guess at the datatype and size so, check you database for the actual values.

You should not be storing plain text passwords. That is a separate topic that you need to research.

Private intLogonAttempts As Integer 'You don't need a Long to hold 3


Private Sub Btn_Login_Click(sender As Object, e As EventArgs) Handles Btn_Login.Click
    Dim RetVal As Integer
    If ValidateInput() Then
        RetVal = GetUserCount(Txt_Username.Text, Txt_Password.Text)
    End If

    If (RetVal = 1) Then
        ' Login successful
        MsgBox("Successful login")
        'Why are you storing this information?
        My.Settings.savedUsername = Txt_Username.Text
        My.Settings.savedPassword = Txt_Password.Text
        My.Settings.Save()
    Else
        ' Login unsuccessful
        intLogonAttempts += 1

        If intLogonAttempts >= 3 Then
            MsgBox("You do not have access to this database. Please contact admin.", vbCritical, "Restricted Access!")
            Application.Exit() 'Of course there is nothing to stop the user from restarting the app and trying 3 more times
            Exit Sub
        Else
            'Don't tell the user what is wrong; that would help unauthorized users
            'It could be the user name or the password
            MsgBox("Please Try Again", vbOKOnly, "Invalid Entry!")
        End If
    End If
End Sub

Private Function ValidateInput() As Boolean
    If Txt_Username.Text = "" Then
        MsgBox("Please enter a username.", vbOKOnly, "Required Data")
        Txt_Username.Select()
        Return False
    End If

    If Txt_Password.Text = "" Then
        MsgBox("Please enter a password.", vbOKOnly, "Required Data")
        Txt_Password.Select()
        Return False
    End If
    Return True
End Function

Private Function GetUserCount(UName As String, UPass As String) As Integer
    'All the database code is here
    Dim RetVal As Integer
    Using connection As New OleDbConnection(My.Settings.DataConnectionString),
            cmd As New OleDbCommand("SELECT Count(*) FROM [User] where [username] = @Name AND [Password] = @PWord;", connection)
        cmd.Parameters.Add("@Name", OleDbType.VarChar, 100).Value = UName
        cmd.Parameters.Add("@PWord", OleDbType.VarChar, 100).Value = UPass
        connection.Open()
        RetVal = CInt(cmd.ExecuteScalar())
    End Using
    Return RetVal
End Function

Upvotes: 1

Shadyjunior
Shadyjunior

Reputation: 457

I forgot the [] around the table name user...

As to not waste this post however, would people be able to suggest if this is perhaps the best way to perform the login or are there better solutions out there?

Upvotes: 0

Related Questions