UPDATE Button not working in VB . and no error is showing [closed] - vb.net

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
datafile = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
connString = provider & datafile
myconnection.ConnectionString = connString
'to update employee status ' not working
myconnection.Open()
Dim str As String
str = "update[HR_Employee_Details]set[Status]='" & cboHREmployeeInfoStatus.Text & "'Where[EmployeeID]='" & txtHREmployeeInfoNewEmployeeID.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, myconnection)
Try
cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox("not updated", MsgBoxStyle.OkOnly, "Update fail")
End Try
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
myconnection.Close()
End Sub

There are some really bad patterns in that code, and as so often happens just updating the code to use better practice will help find the underlying problem. You'll need to read the comments below to see exactly how:
'Isolate and group the DB access in it's own class, module, or class library.
'ALL access to the database in the application should run through here.
Public Module DB
'Move these out of the individual methods, so you don't
'have to repeat them everywhere
Private Readonly Property provider As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
Private Readonly Property datafile As String = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
Private Readonly Property connString As String = provider & datafile
'Each query gets its own public method in this module,
'but everything else should be marked Private
Public Sub UpdateEmployeeStatus(NewStatus As String, EmployeeID As Integer)
'Ole provider for ADO.Net uses ? As parameter placeholders.
'This string could be a CONSTANT!
Dim sql As String = "UPDATE [HR_Employee_Details] SET [Status]= ? WHERE [EmployeeID]= ?"
'The Using block will guarantee your connection is
'closed, even if an exception is thrown.
'The old code could have leaked connection objects
'when there were exceptions.
'Also, ADO.Net works **much** better when you
'create new connection objects for most queries.
Using conn As New OleDbConnection(connString), _
cmd As New OleDbCommand(sql, conn)
'I have to guess at parameter types here.
'You should change this to use exact types &
'lengths from the database.
'ADO.Net will figure out what value goes to
'what parameter based on the order of the
'placeholders in the sql string.
'These parameters are the ONLY correct
'way to include data in an sql command.
'Anything else leaves you open to sql injection.
cmd.Parameters.Add("?", OleDbType.VarWChar, 20).Value = NewStatus
'If this is not an integer, change it to correct type.
'But I wanted to be sure to show two different
'parameter types
cmd.Parameters.Add("?", OleDbType.Integer).Value = EmployeeID
'wait as long as possible to call Open
conn.Open()
cmd.ExecuteNonQuery()
End Using 'No need to call conn.Close() -- the Using block took care of it
End Sub
End Module
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
'Exception handling can still live in the UI
Try
'Again: integer here is just to demonstrate a
'different parameter type.
'If your employee IDs really are strings, it's
'easy to remove this.
Dim EmployeeID As Integer = Integer.Parse(txtHREmployeeInfoNewEmployeeID.Text)
DB.UpdateEmployeeStatus(cboHREmployeeInfoStatus.Text, EmployeeID)
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
Catch ex As Exception
'This is where your real problem was!
'This catch block hid the detail from the exception
'you would need to solve the problem!
'If you don't want to show this to the user, which
'is reasonable, you can at least log it somewhere.
'Once you see the exception message, it will probably
'be much clearer how to fix the issue.
MsgBox($"Error updating the database:{vbCrLf}{Ex.Message}", MsgBoxStyle.OkOnly, "Not Updated")
End Try
End Sub
But so you don't feel like the "good" code needs to be so much longer, here it is again with the comments removed. Especially note how clean the event handler method has become.
Public Module DB
Private Readonly Property provider As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
Private Readonly Property datafile As String = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
Private Readonly Property connString As String = provider & datafile
Public Sub UpdateEmployeeStatus(NewStatus As String, EmployeeID As Integer)
Dim sql As String = "UPDATE [HR_Employee_Details] SET [Status]= ? WHERE [EmployeeID]= ?"
Using conn As New OleDbConnection(connString), _
cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add("?", OleDbType.VarWChar, 20).Value = NewStatus
cmd.Parameters.Add("?", OleDbType.Integer).Value = EmployeeID
conn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
End Module
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
Try
Dim EmployeeID As Integer = Integer.Parse(txtHREmployeeInfoNewEmployeeID.Text)
DB.UpdateEmployeeStatus(cboHREmployeeInfoStatus.Text, EmployeeID)
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
Catch ex As Exception
MsgBox($"Error updating the database:{vbCrLf}{Ex.Message}", MsgBoxStyle.OkOnly, "Not Updated")
End Try
End Sub

Related

How to link to a relational database - visual basic

I am creating a flashcard application where each user can create flashcards which will be specific to them. I was wondering how I can link each flashcard they create to their specific account.
Imports System.Data.OleDb
Public Class CreateFlashcards
Dim pro As String
Dim connstring As String
Dim command As String
Dim myconnection As OleDbConnection = New OleDbConnection
Private Sub btnCreateFlashcard_Click(sender As Object, e As EventArgs) Handles btnCreateFlashcard.Click
pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=flashcard login.accdb"
connstring = pro
myconnection.ConnectionString = connstring
myconnection.Open()
command = " insert into Flashcards ([Front],[Back]) values ('" & txtFront.Text & "','" & txtBack.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(command, myconnection)
cmd.Parameters.Add(New OleDbParameter("username", CType(txtFront.Text, String)))
cmd.Parameters.Add(New OleDbParameter("password", CType(txtBack.Text, String)))
MsgBox("You have successfully added the flashcard into your deck!")
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
myconnection.Close()
txtFront.Clear()
txtBack.Clear()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
This works in that it adds the data into the access database but it does not link to the users account. I have also linked the tables in access
The login table
The flashcard table
As you can see the loginID key does not link
Normally, the connection string for Access contains the the path to the database file for the Data Source attribute.
You will need to add a field to your Flashcard table to hold the UserID. This will tie the 2 tables together.
Database objects like connections and commands need to be disposed as well as closed. Using...End Using blocks handle this for you even if have an error. In this code you both the connection and the command are included in the same Using block.
You can pass the connection string directly to the constructor of the connection. Likewise, pass the sql command text and the connection to the constructor of the command.
When you are using parameters, which you should in Access and Sql Service, put the name of the parameter in the sql command text. It is not necessary to convert the Text property of a TextBox to a string. It is already a String.
I had to guess at the OleDbType for the parameters. Check your database. It is important to note that the order that parameters appear in the sql command text must match the order that they are added to the parameters collection. Access does not consider the name of the parameter, only the position.
I assume you can retrieve the user's ID when they log in to create flash cards. When the user logs in to use there flash cards you would do something like Select * From Flashcards Where LoginID = #UserID;.
Private Sub btnCreateFlashcard_Click(sender As Object, e As EventArgs) Handles btnCreateFlashcard.Click
Try
InsertFlashcard()
MsgBox("You have successfully added the flashcard into your deck!")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub InsertFlashcard()
Dim pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=Path to login.accdb"
Dim Command = " insert into Flashcards (LoginID, [Front],[Back]) values (#Id, #Front, #Back);"
Using myconnection As New OleDbConnection(pro),
cmd As New OleDbCommand(Command, myconnection)
cmd.Parameters.Add("#UserID", OleDbType.Integer).Value = ID
cmd.Parameters.Add("#Front", OleDbType.VarChar).Value = txtFront.Text
cmd.Parameters.Add("#Back", OleDbType.VarChar).Value = txtBack.Text
myconnection.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
EDIT
As per comment by ADyson I have added code to retrieve ID. Of course in your real application you would be salting and hashing the password. Passwords should never be stored as plain text.
Private ID As Integer
Private Sub btnLogIn_Click(sender As Object, e As EventArgs) Handles btnLogIn.Click
Dim pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=Path to login.accdb"
Using cn As New OleDbConnection(pro),
cmd As New OleDbCommand("Select LoginID From login Where Username = #Username and Password = #Password;")
cmd.Parameters.Add("#Username", OleDbType.VarChar).Value = txtUserName.Text
cmd.Parameters.Add("#Password", OleDbType.VarChar).Value = txtPassword.Text
cn.Open()
Dim result = cmd.ExecuteScalar
If Not result Is Nothing Then
ID = CInt(result)
Else
MessageBox.Show("Invalid Login")
End If
End Using
End Sub

Login form in VB.NET doesn't allow user to login after they've entered login details incorrectly before entering the correct login details

I have a multi-level access login form made in VB.NET that uses an Access database in the back end.
If the user tries to log in when there is nothing entered in either of the text boxes (presses the log in button with nothing entered into either of the text boxes) and then tries to log in after entering their correct details, it allows it.
However, when the user enters either the username or password wrong, it will not allow them to log in after they have entered the correct details.
I am also having a problem where there is no case sensitivity (as long as the password has the correct characters in the correct order it doesn't matter if it is in upper case or lower case).
Imports System.Data.OleDb
Public Class frmLogin
Private DBCon As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" &
"Data Source=|DataDirectory|\NewHotel.mdb;")
Private Sub btnLogIn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogIn.Click
If txtUsername.Text = "" Or txtPass.Text = "" Then
lblErrorEmpty.Visible = True
Else
Try
DBCon.Open()
Using cmd As New OleDbCommand("SELECT * FROM tblEmployees WHERE [Username] = #Usernname AND [Pass] = #Pass", DBCon)
cmd.Parameters.AddWithValue("Username", OleDbType.VarChar).Value = txtUsername.Text.Trim
cmd.Parameters.AddWithValue("Pass", OleDbType.VarChar).Value = txtPass.Text.Trim
Dim DBDA As New OleDbDataAdapter(cmd)
Dim DT As New DataTable
DBDA.Fill(DT)
If DT.Rows(0)("Type") = "Manager" Then
frmHomeManager.Show()
ElseIf DT.Rows(0)("Type") = "Receptionist" Then
frmHomeReceptionist.Show()
End If
End Using
Catch ex As Exception
lblErrorMatch.Visible = True
End Try
End If
End Sub
Thank you for your time :)
Don't declare connections outside of the method where they are used. Connections need to be closed and disposed. Using...End Using blocks handle this even when there is an error.
I have separated the user interface code from the database code. This makes the code easier to maintain
For OleDb the .Add method for parameters will help. Don't open the connection until directly before the .Execute. You are only retrieving a single piece of data so .ExecuteScalar should do the trick.
Private ConStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\NewHotel.mdb;"
Private Sub btnLogIn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogIn.Click
If txtUsername.Text = "" OrElse txtPass.Text = "" Then
MessageBox.Show("Please fill in both User Name and Password")
Exit Sub
End If
Dim UserType As Object
Try
UserType = GetUserType(txtUsername.Text.Trim, txtPass.Text.Trim)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
If UserType Is Nothing Then
MessageBox.Show("No record found")
ElseIf UserType.ToString = "Manager" Then
frmHomeManager.Show()
ElseIf UserType.ToString = "Receptionist" Then
frmHomeReceptionist.Show()
Else
MessageBox.Show($"{UserType} is not listed.")
End If
End Sub
Private Function GetUserType(UserName As String, Password As String) As Object
Dim Type As Object
Using DBCon As New OleDb.OleDbConnection(ConStr),
cmd As New OleDbCommand("SELECT Type FROM tblEmployees WHERE [Username] = #Usernname AND [Pass] = #Pass", DBCon)
cmd.Parameters.Add("#Username", OleDbType.VarChar).Value = UserName
cmd.Parameters.Add("#Pass", OleDbType.VarChar).Value = Password
DBCon.Open()
Type = cmd.ExecuteScalar.ToString
End Using
Return Type
End Function
Your check for the password is case insensitive, because you are storing the password directly and the database is case insensitive.
Your major problem is that you shouldn’t be storing the password in the database, you should be storing a cryptographically secure hash of the password in the database. This will require more work, but will be much safer.
You don’t have enough details to say why you can’t make a second attempt. I will say for reading a single record, I wouldn’t use a data table.

VB.Net Inserting DateTimePicker to MS Access Database

Good day to everyone here at stackoverflow! I have a simple question that maybe you guys could help me out with. I created a prototype for inserting a DateTimePicker into the MS Access database. I followed this guide:
date time conversion problem when inserting data into sql database and although it helped the person asking the question, it did not help me at all :(
This is the picture and this is my code. This is just a simple prototype that if solved, I will be able to implement it into the actual system I am working on with my classmates.
There is a syntax error apparently. But if I remove just the datetimepicker codes I can insert my last name without any problems and have it show up in MS Access. These are the codes.
Imports System.Data.OleDb
Public Class Form1
Dim conString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Israel De Leon\Documents\dateinsert.accdb;"
Dim con As OleDbConnection = New OleDbConnection(conString)
Dim cmd As OleDbCommand
Dim adapter As OleDbDataAdapter
Dim dt As DataTable = New DataTable()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListView1.View = View.Details
ListView1.FullRowSelect = True
ListView1.Columns.Add("Last Name", 100)
ListView1.Columns.Add("Date", 100)
End Sub
Public Sub add()
Dim SQL As String = "INSERT INTO Table1(LastName, Time) VALUES (#LastName, #Time)"
cmd = New OleDbCommand(SQL, con)
cmd.Parameters.AddWithValue("#LastName", TextBox1.Text)
cmd.Parameters.AddWithValue("#Time", DateTime.Parse(DateTimePicker1.Value))
'OPEN CONNECTION AND INSERT
Try
con.Open()
If cmd.ExecuteNonQuery() > 0 Then
MsgBox("Succesfully Inserted")
End If
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
add()
End Sub
End Class
Please help this mate out. Thank you :D
The problem is the name of the column Time. Time is a reserved word in MS-Access. You need to put square brackets around that name
Dim SQL As String = "INSERT INTO Table1(LastName, [Time]) VALUES (#LastName, #Time)"
I also strongly suggest you to not use AddWithValue, but the more precise Add where you can properly set the datatype of your parameter and avoid the hidden code of AddWithValue that translates your inputs to the expected ones
cmd.Parameters.Add("#LastName", OleDbType.VarWChar, 100).Value = TextBox1.Text
cmd.Parameters.Add("#Time", OleDbType.DateTime).Value =DateTimePicker1.Value
Notice that the Add method allows you to define also the size of your data in case of text. This allows the database engine to optimize your insert query. (Not sure if this happens also with access but surely with Sql Server this is an important optimization)
Better to use monthCalendar control:
textBox1.Text = monthCalendar1.SelectionRange.Start.Date.ToShortDateString()
cmd.Parameters.AddWithValue("#Time", textBox1.Text)

VB.Net - Inserting data to Access Database using OleDb

Can you please tell me what's wrong with the code I'm using? Everytime I execute this, it throws the exception (Failed to connect to database)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim conn As New System.Data.OleDb.OleDbConnection()
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\socnet.accdb"
Dim sql As String = String.Format("INSERT INTO login VALUES('{username}','{password}','{secques}','{secans}')", txt_username.Text, txt_passwd.Text, txt_secquestion.Text, txt_secansw.Text)
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
'Open Database Connection
sqlCom.Connection = conn
conn.Open()
Dim icount As Integer = sqlCom.ExecuteNonQuery
MessageBox.Show(icount)
MessageBox.Show("Successfully registered..", "Success", MessageBoxButtons.OK, MessageBoxIcon.Error)
Catch ex As Exception
MessageBox.Show("Failed to connect to Database..", "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
cmd_submit2_Click(sender, e)
End If
End Sub
I am using Access 2013 and VS 2015 Community, if that helps. Thank you.
You should use a parameterized approach to your commands.
A parameterized query removes the possibility of Sql Injection and you will not get errors if your string values are not correctly formatted.
Note that if you don't do anything in the exception block then it is better to remove it and let the exception show itself or at least show the Exception.Message value, so you are informed of the actual error.
Finally every disposable object should be created with the Using statement that ensures a proper close and dispose of such objects (in particular the OleDbConnection)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sql As String = "INSERT INTO login VALUES(#name, #pass, #sec, #sw)"
Using conn = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\socnet.accdb")
Using sqlCom = New System.Data.OleDb.OleDbCommand(sql, conn)
conn.Open()
sqlCom.Parameters.Add("#name", OleDbType.VarWChar).Value = txt_username.Text
sqlCom.Parameters.Add("#pass", OleDbType.VarWChar).Value = txt_passwd.Text
sqlCom.Parameters.Add("#sec", OleDbType.VarWChar).Value = txt_secquestion.Text
sqlCom.Parameters.Add("#sw", OleDbType.VarWChar).Value = txt_secansw.Text
Dim icount As Integer = sqlCom.ExecuteNonQuery
End Using
End Using
End Sub
Keep in mind that omitting the field names in the INSERT INTO statement requires that you provide values for every field present in the login table and in the exact order expected by the table (So it is better to insert the field names)
For example, if your table has only the 4 known fields:
Dim sql As String = "INSERT INTO login (username, userpass, secfield, secfieldsw) " & _
"VALUES(#name, #pass, #sec, #sw)"

Please help me update records of access filenames "Data.accdb"in Vb.net using oledb connection

Getting Error While Updating Record.
Firs of all i select a row from Datagrid then selected row's values displayed to textbox then i click update button to update record.
After entered New usename and password click save Buton then getting error as follow.
ERROR
system.data.oledb.oledbException(0x80040e14):syntax error in UPDATE statement.
at
system.data.oledb.oledbCommand.executeCommandTextErrorHandling(Oledb Hresult hr)
at
System.data.Oledb.OledbCommand.ExecutecommandTextforSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at
System.data.Oledb.OledbCommand.Executecommand(CommandBehavior Behavior, String method)
at System.data.Oledb.OledbCommand.ExecuteNonQuery()
at Nakul.frmusers.cmdsave_click(object sender, EventArgs e)in
E:\kul....\frmusers.vb:line 152
Note : I did not want to update the userid.
Data.accdb // Access File Name
table Name : users
Design View: userid Number // primary key
username text
password text
Imports System.Data
Imports System.Data.OleDb
public class users
Dim str As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\kul\Data.accdb;Persist Security Info=False;"
Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
Dim conn As New OleDbConnection(str)
Dim qry As New OleDbCommand("update users set username='" & txtusername.Text & "', password='" & txtpassword.Text & "' where userid=" & txtuserid.Text, conn)
Try
conn.Open()
qry.ExecuteNonQuery() // Error Line No 152 in Coading
conn.Close()
MsgBox("Record Updated")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End class
The main reason for the Syntax error is the word PASSWORD. It is a reserved keyword in Access and thus you need to encapsulate it with square brackets
Said that, you need to change you query and use a parameterized approach and not a string concatenation. Building your query concatenating strings could be another source of syntax errors (a user name that contains a single quote?) and open the door to sql injection attacks
Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
dim query = "update users set username=?, [password]=? where userid=?"
Using conn = new OleDbConnection(str)
Using qry = New OleDbCommand(query, conn)
qry.Parameters.AddWithValue("#p1",txtusername.Text )
qry.Parameters.AddWithValue("#p2",txtpassword.Text )
qry.Parameters.AddWithValue("#p3",Convert.ToInt32(txtuserid.Text))
conn.Open()
qry.ExecuteNonQuery()
conn.Close()
MsgBox("Record Updated")
End Using
End Using
End Sub
Also note the using statement that ensure the correct closing and disposing of the connection and the command.