How to update data in MS Access Database - vb.net

just want to ask if what is the proper way on updating data in ms access Database, because when I use this code, my data is not updated and it doesn't show any error, so the returned value of the function is FALSE.
below is my code.
dim conn as new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\myDb.accdb;Persist Security Info=False;")
Protected Function UpdateProduct(ByVal productDetails As ProductModel) As Boolean
reopenConnection()
cmd = New OleDbCommand("UPDATE Product Set ProductName=#prodName, Price=#price, ProductDescription=#prodDesc, CategoryId=#catId where ProductId=#prodId;", conn)
cmd.CommandType = CommandType.Text
cmd.Parameters.Add("#prodId", OleDbType.VarChar).Value = productDetails.NewProductId
cmd.Parameters.Add("#prodName", OleDbType.VarChar).Value = productDetails.ProductName
cmd.Parameters.Add("#price", OleDbType.Decimal).Value = productDetails.Price
cmd.Parameters.Add("#prodDesc", OleDbType.VarChar).Value = productDetails.ProductDescription
cmd.Parameters.Add("#categoryId", OleDbType.Integer).Value = productDetails.CategoryId
Return cmd.ExecuteNonQuery() > 0
End Function
Private Sub reopenConnection()
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.Open()
End Sub
Thanks

My experience with access is you have to commit the transactions or you never see the update in the database. See this stackoverflow thread for the syntax.
How to implement transaction way in vb.net?

Related

How to add edited date automatically to datetimepicker?

I want to make the time will fill automatically in Datetimepicker when I edit the price of my product. So, it can compare to the date of buying. So, I decided to use on_update_current_timestamp in MySQL database. My problem is how to convert a string into a date in Datagridview. Because when I was press the edit button it works but for the add button it's getting an error unable to convert MySQL date/time Is it have any solution to achieve my goal. If yes can u explain it. Thank u
Public Sub disp_data()
cmd = conn.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "select * from produk"
cmd.ExecuteNonQuery()
Dim dt As New DataTable()
Dim da As New MySqlDataAdapter(cmd)
da.Fill(dt)
DataGridView1.DataSource = dt
End Sub
Private Sub tambah_btn_Click(sender As Object, e As EventArgs) Handles tambah_btn.Click
cmd = conn.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = $"insert into produk values('{kode.Text}','{nama.Text}','{harga.Text}','{DateTimePicker1.Value.ToString("dd/mm/yyyy")}')"
cmd.ExecuteNonQuery()
kode.Text = ""
nama.Text = ""
harga.Text = ""
disp_data()
MessageBox.Show("Data berhasil ditambahkan")
End Sub
You can do it (and it's better) like this:
'...
cmd = conn.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "insert into produk values (#kode,#nama,#harga,#date)"
cmd.Parameters.AddWithValue("#kode", kode.Text)
cmd.Parameters.AddWithValue("#nama", nama.Text)
cmd.Parameters.AddWithValue("#harga", harga.Text)
cmd.Parameters.AddWithValue("#date", DateTimePicker1.Value.Date)
cmd.ExecuteNonQuery()
'...
let me know if it solves it, or if some adjustments are needed

could not update currently locked vb.net error

I want to Insert 2 different data in 2 different table of ms-access.
And it shows this error.
I have a code like this:
try
dim sql1,sql2 as string
sql1 = "INSERT INTO table1(something)VALUES(something)"
cmd = new oledbcommand(sql1, connection)
cmd.executenoquery()
sql2 = "INSERT INTO table2(something)VALUES(something)"
cmd2 = new oledbcommand(sql2, connection)
cmd2.executenoquery()
catch ex as exception
msgbox(ex.tostring())
(where these cmd1,cmd2 are defined in controlModule.)
so,what should I do ?
Any help is appreciated. Thank You
I think closing the connection fixes the issue, best by using the Using-statement:
try
Using con As OleDbConnection = GetConnection() ' or New OlebConnection(...)
Using cmd = con.CreateCommand()
cmd.CommandText = "INSERT INTO table1(something)VALUES(#something)"
cmd.Parameters.AddWithValue("#something", something)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Using con As OleDbConnection = GetConnection()
Using cmd = con.CreateCommand()
cmd.CommandText = "INSERT INTO table2(something)VALUES(#something)"
cmd.Parameters.AddWithValue("#something", something)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Catch ex As Exception
msgbox(ex.tostring())
End Try
This is a concurrency issue. Because some other part of your code or MS Access itself accesses the database at the same time.
The fact is that you're not closing the connection after it's use. So the 2nd call should fail with that exception. Instead, you should wrap your disposables - e.g. the OleDbConnection, commands, etc. - in a using statement. That way, the connection will be closed, even if an exception occur:
Using con As New OleDbConnection, cmd1 As OleDbCommand = con.CreateCommand, cmd2 As OleDbCommand = con.CreateCommand()
cmd1.CommandText = "INSERT INTO table1(something)VALUES(something)"
cmd1.ExecuteNonQuery()
cmd2.CommandText = "INSERT INTO table2(something)VALUES(something)"
cmd2.ExecuteNonQuery()
End Using

Updating Table from vb to Access using ConnectionString

Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Try
Dim con As New SqlConnection
Dim cmd As New SqlCommand
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Comp-296\Project1\Project1\Game_time.mdb"
con.Open()
cmd.Connection = con
cmd.Connection = con
cmd.CommandText = ("UPDATE User_Name SET User_Name = #User_Name, Game_Name = #Game_Name, Score = #Score, Time/Date = #Time/Date")
cmd.Parameters.Add("#User_Name", SqlDbType.VarChar).Value = txtUser.Text
cmd.Parameters.Add("#Game_Name", SqlDbType.VarChar).Value = txtGame.Text
cmd.Parameters.Add("#Score", SqlDbType.VarChar).Value = txtScore.Text
cmd.Parameters.Add("#Time/Date", SqlDbType.DateTime).Value = txtDate.Text
cmd.ExecuteNonQuery()
MessageBox.Show("Data Update successfully")
con.Close()
Catch ex As System.Exception
MessageBox.Show("Data Update has failed")
End Try
End Sub
The code is giving an Exception is an ArgumentException and also :Keyword not supported: 'provider'.
You are using Access. This database cannot be opened using the classes in System.Data.SqlClient. These classes are used when you want to connect to Sql Server, Sql Server Express or LocalDB.
If you want to reach an MSAccess database you need the classes in System.Data.OleDb and these classes are OleDbConnection, OleDbCommand etc...
Said that, please note, that your field Date/Time will give you headaches. Change that name or put always square brackets around it because the / will be interpreted as the division operator
So your code could be:
Using con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Comp-296\Project1\Project1\Game_time.mdb")
Using cmd = new OleDbCommand("UPDATE User_Name
SET User_Name = #User_Name,
Game_Name = #Game_Name,
Score = #Score, [Time/Date] = #dt", con)
con.Open()
cmd.Parameters.Add("#User_Name", OleDbType.VarWChar).Value = txtUser.Text
cmd.Parameters.Add("#Game_Name", OleDbType.VarWChar).Value = txtGame.Text
cmd.Parameters.Add("#Score", OleDbType.VarWChar).Value = txtScore.Text
cmd.Parameters.Add("#dt", OleDbType.Date).Value = Convert.ToDateTime(txtDate.Text)
cmd.ExecuteNonQuery()
MessageBox.Show("Data Update successfully")
End Using
End Using
Other notes:
Disposable objects like the connection and the command should be enclosed inside a Using Statement to be disposed and closed as soon as possible.
The time field requires a DateTime value not a string. If you pass a string you will face the automatic conversion made by the engine and sometime the engine is unable to produce a valid date from your input string. This will raise another exception (DataType mismatch). Better check and convert the value before passing it.
Also the type of the parameters should be from the OleDbType enum.

ExecuteReader() Object reference not set to an instance of an object error

I am trying to figure out why I am getting an error of 'Object reference not set to an instance of an object.' when my winforms code runs. I have set a breakpoint on the sql statement and stepped into the code and it shows as the line: Using dr = oledbCmd.ExecuteReader()
I am still learning vb.Net so would appreciate some help as to how to overcome this error. Many thanks
DBConnection.connect()
sql = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
Dim cmd As New OleDb.OleDbCommand
cmd.Parameters.AddWithValue("#p1", cmbCustomer.Text)
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
Using dr = oledbCmd.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
End Using
cmd.Dispose()
dr.Close()
oledbCnn.Close()
DBConnect module
Imports System.Data.OleDb
Module DBConnection
Public connetionString As String = My.Settings.storageConnectionString
Public oledbCnn As New OleDbConnection
Public oledbCmd As OleDbCommand
Public dr As OleDbDataReader
Public sql As String
Sub connect()
'connetionString = My.Settings.storageConnectionString
oledbCnn.ConnectionString = connetionString
oledbCnn.Open()
End Sub
End Module
I saw several mistakes. Look to the comments for reasons for the changes
Dim sql As String = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
'.Net uses connection pooling, such that you're better using a new connection object for each query
'Also, a Using block will ensure the connection is closed, **even if an exception is thrown**
' The original code would leak connections when exceptions occured, eventually locking you out of the db
Using cn As New OleDb.OleDbConnection("Connection string here"), _
cmd As New OleDb.OleDbCommand(sql, cn) 'set CommandText BEFORE adding parameters
'Use explicit parameter types
cmd.Parameters.Add("?", SqlDbType.NVarChar, 50).Value = cmbCustomer.Text
cn.Open()
Using dr As OleDb.OleDbDataReader = cmd.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
dr.Close()
End Using
End Using
You have failed to properly bind the SqlConnection to the SqlCommand object.
Using connection As New SqlConnection(connectionString)
connection.Open()
Dim command As New SqlCommand(queryString, connection)
Dim reader As SqlDataReader = command.ExecuteReader()
While reader.Read()
Console.WriteLine("{0}", reader(0))
End While
End Using
See: MSDN
Edit: Requested adjustment to aid in clarity:
Using connection As New Data.SqlClient.SqlConnection
Dim sql As String = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
connection.Open()
Using command As New Data.SqlClient.SqlCommand(Sql, connection)
command.Parameters.AddWithValue("#p1", cmbCustomer.Text)
dr = command.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
MediaTypeNames.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
End Using
End Using
Your code should look something like that.
you have a fair amount of potential issues going on here.
1-you are using your dr variable twice. once before the using, which is probably causing your error. then again in for using, which does not look right because it is not the cmd variable used to execute the reader. so change this part of your code:
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
Using dr = oledbCmd.ExecuteReader()
to this:
cmd.CommandText = sql
cmd.Connection = oledbCnn
Using dr = cmd.ExecuteReader()
2-you are not showing if oledbCnn has been opened yet. I'm assuming your DBConnection.connect() function is doing this and olebCnn is a variable that function sets and opens
3-I'm not sure if the question mark in your query string will work. Even if it does you should replace it with the parameter name. so your query string should be:
sql = "SELECT * from Boxes WHERE Customer = #p1 AND Status = 'I'"
lastly you should probably show all the code for the sub(or function) this is for so we can get a full picture. example dr must be declared before the using else you would get a build error.

Update MS Access via vb.net

the below code runs without error, but the MS Access table isn't updating. What am I missing?
Try
cnn = New OleDbConnection(ConfigurationManager.ConnectionStrings("accConnectionString").ToString())
cnn.Open()
Catch ex As Exception
Debug.Print("Oops - no connection to database")
Exit Sub
End Try
Dim sql As String
sql = "SELECT * FROM tblSend WHERE UploadedSuccessfullyOn is null ORDER BY QueuedOn;"
Dim da As New OleDbDataAdapter(sql, cnn)
Dim ds As New DataSet
da.Fill(ds, "dsQueuedToSend")
For Each dr As DataRow In ds.Tables("dsQueuedToSend").Rows
' Perform other unrelated tasks in this space, removed for brevity
' If those other tasks were successful, update Access.
If success = True Then
sql = "UPDATE [tblSend] SET [UploadedSuccessfullyOn] = #uploadedOn WHERE (([UploadID]) = #uploadId);"
Dim cmd As OleDbCommand
cmd = New OleDbCommand(sql, cnn)
cmd.Parameters.Add("#uploadedOn", OleDbType.Date).Value = Now
cmd.Parameters.Add("#uploadedId", OleDbType.Integer).Value = dr("UploadID")
cmd.ExecuteNonQuery()
cmd.Dispose()
Console.WriteLine("Success: updated.")
Else
Console.WriteLine("Failed: Not updated.")
End If
Next
da.Dispose()
cnn.Close()
I've also tried with:
sql = "UPDATE [tblSend] SET [UploadedSuccessfullyOn] = ? WHERE (([UploadID]) = ?);"
Or simply add the values in the not-preferred/non-parameter approach:
sql = "UPDATE [tblSend] SET [UploadedSuccessfullyOn] = #" & Now & "# WHERE (([UploadID]) = " & dr("UploadID") & ");"
Dim cmd As OleDbCommand
cmd = New OleDbCommand(sql, cnn)
cmd.ExecuteNonQuery()
cmd.Dispose()
None of these approaches updates the MS Access table. Ideas? Thanks!
One thing I have been caught by before with Visual Studio is that when embedding an Access database in a WinForms project, when you run the project, the Access database is copied over from the original to the runtime directory, overwriting any changes you've made.
This can create the illusion that an update is not taking place, when in fact if you check at the right moment, it is.