Why is my database not updating? - vb.net

My problem is that when I am editing cells in the datagrid the database is not updating.
The code I used is below.
Public Class Form9
Inherits System.Windows.Forms.Form
Dim sql As String = "SELECT * FROM User_Account WHERE IsAdmin=False"
Dim conn As New OleDb.OleDbConnection
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql, conn)
Dim da As New OleDb.OleDbDataAdapter(sqlCom)
Dim dt As New DataTable
Private Sub Form9_Load(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Load
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & _
folderpath & "\TKIC\TKIC_Data_Storage.accdb'" & _
";Persist Security Info=True"
conn.Open()
da.Fill(dt)
DataGridView1.DataSource = dt
End Sub
Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs)
DataGridView1.Update()
dt.AcceptChanges()
End Sub
End Class

You have to update the underlying DataTable. The DataGridView.Update causes the control to redraw the invalidated regions within its client area (basically repaints). The dt.AcceptChanges() only commits the changes in the DataTable not the database. The database has to be updated explicitly using the adapter and appropriate command texts. The OleDbCommandBuilder helps in forming the appropriate command texts.
Use the OleDbDataAdapter to update the database.
OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
cb.QuotePrefix = "[";
cb.QuoteSuffix = "]";
adapter.Update(datatable);

Related

How does one access datagridview components when data is preloaded in?

I want to be able to access the table so that I can add DataGridView.AutoSizeColumnsMode to fill, and also so that I can access the rest of the table so that I can code add, edit and remove buttons that access the database.
I'm just not sure how to do it because I'm unfamiliar with databases, loading them and saving them
'Declarations
Dim con As New SqlClient.SqlConnection
Dim ds As New DataSet
Dim sqlString As String = "SELECT * FROM Items"
Dim da As New SqlClient.SqlDataAdapter(sqlString, con)
'Opening Load
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
con.ConnectionString = "Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=|DataDirectory|\db.mdf;Integrated Security=True"
con.Open()
da.Fill(ds, "ItemsTable")
DataGridView1.DataSource = ds.Tables("ItemsTable")
End Sub

Display different data from a single field to multiple textbox (VB 2010/MS Acess)

I just want to ask this question (the title). I have a column named PR_rating and I need to display the values to TextBoxes according to student ID so one student ID= many PR_rating. My problem is I don't know how to do that. The TextBox just shows all the values in one TextBox. Sorry for my bad English.
Imports System.Data.OleDb
Public Class adminEval
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Billy\Desktop\TH\exampleData.accdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
End Sub
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
myConnection.Open()
Dim str As String
str = "SELECT * FROM [Transaction] WHERE (Stud_no ='" & txtstudnum.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
txteng11.Text &= dr(7).ToString() & Environment.NewLine
It might be better to use something other than a textbox to store this data. I prefer putting the code into a datatable and then load this into a datagridview.
Below is an example using your code:
'new variables added for this example
dim dataAdapter as New OldDbDataAdapter
dim dataTable as New DataTable
dim dataGrid as New DataGridView
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
myConnection.Open()
Dim str as String
str = "SELECT * FROM [Transaction] WHERE (Stud_no=#studentNum)"
Dim cmd as OleDbCommand = New OleDbCommand(str, my connection)
'Use parameters to safely fill the SQL string
cmd.Parameters.Add("#studentNum",OleDbType.String).value = txtstudnum.Text
dataAdapter.SelectCommand = cmd
'fill the dataTable using the dataAdapter, which has been executed above
dataAdapter.Fill(dataTable)
'Use the dataTable as the dataGrid's source to add the data into it
dataGrid.DataSource = dataTable
myConnection.Close()
End Sub
Above I also use the OleDbCommand parameters. This allows you to safely fill your SQL string for execution.
Using a Data Adapter you can put the data into this from your command and use this data to fill a dataTable. Once the table is filled you can populate your dataGridView on your form (inserted from the toolbox to your form) by setting the table as your DataSource.
Apologies if this is not suited to your needs, I usually do this with MySQL, so OleDB is new to me, but similar syntax.

VB.Net OleDBConnection code to update access database from DataGridView

I have a simple userform with a DataGridView and I would like to use OleDB code to update the accdb database based on any entries made in the gridview. The load button works fine, but the save button produces this error:
Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
Here is my code:
Imports System.Data.OleDb
Public Class Form1
Dim myConString As String
Dim con As OleDbConnection = New OleDbConnection
Dim Dadapter As OleDbDataAdapter
Dim DSet As DataSet
Dim DSet2 As DataSet
Dim ConCMD As OleDb.OleDbCommand
Private Sub load_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles load_btn.Click
myConString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\Psmccsfs01\snd\PRODUCTION\Licensed\Reporting\FTO Adjustment Tools\FTO_Log_DB.accdb;"
con.ConnectionString = myConString
con.Open()
Dadapter = New OleDbDataAdapter("select * from FTO_Log", con)
DSet = New DataSet
Dadapter.Fill(DSet, "FTO_Log")
DataGridView1.DataSource = DSet.Tables("FTO_Log")
con.Close()
End Sub
Private Sub save_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles save_btn.Click
Using con = New OleDbConnection(myConString)
con.Open()
Dadapter.Update(DSet, "FTO_Log")
End Using
End Sub
End Class
dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = #CategoryName " +
"WHERE CategoryID = #CategoryID", connection);
notice the typo in the code above, straight from the msdn site ;p
short and simple: http://msdn.microsoft.com/en-us/library/33y2221y%28v=vs.110%29.aspx

Syntax error in INSERT into statement when adding to access database

Someone please help me on finding the error on my code.
the error is at the line inside my try and catch where im trying to add record on my database Access. the error is "Syntax error in INSERT into statement". I already tried using
ds.Tables("Users").Rows.Add(dsNewRow)
da.Update(ds, "Users")
on my registration for voters and it works fine. idk why it doesnt work on this form (user registration).
Imports System.Data.OleDb
Public Class UserRegister
Dim con As New OleDb.OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim ds As New DataSet
Dim da As New OleDb.OleDbDataAdapter
Dim sql As String
Private Sub Label4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label4.Click
End Sub
Private Sub UserRegister_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbProvider = " PROVIDER=Microsoft.jet.OLEDB.4.0;"
dbSource = "Data Source= C:\Users\Ronel\Documents\database\CSdatabase.mdb"
con.ConnectionString = dbProvider & dbSource
con.Open()
sql = "SELECT*FROM tblUsers"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "Users")
MsgBox("Database now Open")
con.Close()
'MsgBox("Database now Close")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim cb As New OleDb.OleDbCommandBuilder(da)
Dim dsNewRow As DataRow
Dim empty =
Me.Controls.OfType(Of TextBox)().Where(Function(txt) txt.Text.Length = 0)
If empty.Any Then
MessageBox.Show(String.Format("PLEASE FILL ALL FIELDS:"))
Else
dsNewRow = ds.Tables("Users").NewRow()
dsNewRow.Item("Username") = TextBoxUser.Text
dsNewRow.Item("Password") = TextBoxPass.Text
dsNewRow.Item("LastName") = TextBoxFN.Text
dsNewRow.Item("GivenName") = TextBoxGN.Text
dsNewRow.Item("MiddleName") = TextBoxMN.Text
' Try
ds.Tables("Users").Rows.Add(dsNewRow)
da.Update(ds, "Users")
' Catch ex As Exception
MsgBox("Error updating")
' End Try
' Me.Dispose()
'Comelec.Show()
End If
End Sub
End Class
I see a few problems. First, your SQL statement needs some spaces in it. Instead of sql = "SELECT*FROM tblUsers", use sql = "SELECT * FROM tblUsers".
Second, when using OleDbCommandBuilder, the code connects to the database using the SELECT statement you provided for the DataAdapter, and uses that to generate the necessary SQL for Update, Delete, and Insert statements. The connection to the database needs to be open for this to occur -- you connection is closed at the point where the CommandBuilder is running. This is probably where the syntax error is coming from.
The CommandBuilder will create these statements using all of the fields specified in the SELECT. If you have fields in your Users table other than the five you are attempting to populate, the OleDbCommandBuilder is still going to build an INSERT statement that will attempt to fill those fields as well. Depending on how your table is structured, this may cause rows to be rejected if required fields aren't populated. To take a look at what SQL statements are being generated, you can look at properties of the DataAdapter object after using the CommandBuilder:
con.Open
sql = "SELECT * FROM tblUsers"
da = New OleDb.OleDbDataAdapter(sql, con)
Dim cb As New OleDb.OleDbCommandBuilder(da)
Debug.Print("SELECT: " & da.SelectCommand.CommandText)
Debug.Print("UPDATE: " & da.UpdateCommand.CommandText)
Debug.Print("DELETE: " & da.DeleteCommand.CommandText)
Debug.Print("INSERT: " & da.InsertCommand.CommandText)
Some additional reading on CommandBuilders is available here: http://msdn.microsoft.com/en-us/library/tf579hcz%28v=vs.110%29.aspx
Give this a try:
Imports System.Data.OleDb
Public Class UserRegister
Const dbProvider As String = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
Dim dbSource As String = "Data Source=C:\Users\Ronel\Documents\database\CSdatabase.mdb"
Dim con As New OleDb.OleDbConnection(dbProvider & dbSource)
Dim ds As New DataSet
Dim da As New OleDb.OleDbDataAdapter
'Specify only the fields you need
Dim sql As String = "SELECT UserName, Password, LastName, GivenName, MiddleName FROM tblUsers"
Private Sub UserRegister_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
con.Open()
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "Users")
' Get commands now, while connection is open. Do this once when the form is loaded, not every time button is clicked.
Dim cb As New OleDb.OleDbCommandBuilder(da)
con.Close()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Validation code goes here
If empty.Any Then
MessageBox.Show(String.Format("PLEASE FILL ALL FIELDS:"))
Else
Dim dsNewRow As DataRow
dsNewRow = ds.Tables("Users").NewRow()
dsNewRow.Item("Username") = TextBoxUser.Text
dsNewRow.Item("Password") = TextBoxPass.Text
dsNewRow.Item("LastName") = TextBoxFN.Text
dsNewRow.Item("GivenName") = TextBoxGN.Text
dsNewRow.Item("MiddleName") = TextBoxMN.Text
Try
con.Open()
ds.Tables("Users").Rows.Add(dsNewRow)
da.Update(ds, "Users")
Catch ex As Exception
MsgBox("Error updating: " & Err.Description)
Finally
con.Close()
End Try
End If
End Sub
End Class

Syntax error (missing operator) in query expression 'Prod_Num ='

This Syntax error (missing operator) in query expression 'Prod_Num ='. always shows up when I'm trying to search an item in the database. Please help me.
Imports System
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
Dim con As New OleDb.OleDbConnection
Dim cmd As OleDbCommand
Dim da As OleDb.OleDbDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
Dim sql As String
Dim dbp As String
Dim dbs As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbp = "Provider = Microsoft.ACE.OLEDB.12.0;"
dbs = "Data Source=" & Application.StartupPath & "/POS.accdb"
con.ConnectionString = dbp & dbs
con.ConnectionString = dbp & dbs
con.Open()
sql = "SELECT * FROM tblInventory"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(dt)
dgList.DataSource = dt
txtPNum.Focus()
End Sub
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
dt.Clear()
txtPNum.Text = ""
sql = "SELECT * FROM tblInventory WHERE Prod_Num =" & txtPNum.Text
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(dt)
dgList.DataSource = dt
txtPName = dt.Rows(0).Item(1)
txtNOrder = dt.Rows(0).Item(2)
txtPRem = dt.Rows(0).Item(3)
txtPrice = dt.Rows(0).Item(4)
txtPNum.Focus()
End Sub
My guess is that you have problem here:
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
dt.Clear()
txtPNum.Text = "" ' <-----------------
sql = "SELECT * FROM tblInventory WHERE Prod_Num =" & txtPNum.Text
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(dt)
dgList.DataSource = dt
txtPName = dt.Rows(0).Item(1)
txtNOrder = dt.Rows(0).Item(2)
txtPRem = dt.Rows(0).Item(3)
txtPrice = dt.Rows(0).Item(4)
txtPNum.Focus()
End Sub
Remove this line:
txtPNum.Text = ""
Since you always clears the txtPNum textbox's text before passing it to the query.
NOTE:
Don't forget to implement it via parameterized query. This is not a good approach.
See parameterized query examples:
Example 1
Example 2
Hope it helps!
does txtPNum.Text contain any data?
Why don't you try checking that, because if it is empty your running SQL statement is "SELECT * FROM tblInventory WHERE Prod_Num =" which would raise that error.
Also if the Prod_Num column is integer, perhaps you should use int(txtPNum.Text) if that value is a string, this would also prevent SQL Injection.
In addition to the problem with txtPNum.Text that others have pointed out, I would recommend a couple of other things:
Use parameterized queries to avoid SQL Injection.
Use Using blocks with your connection, and close the connection as soon as you are done. In your Form_Load, for example, you open the connection and leave it open. That is not good practice.
Example:
Imports System
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
Dim con As OleDbConnection
Dim cmd As OleDbCommand
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
Dim dbp As String
Dim dbs As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbp = "Provider = Microsoft.ACE.OLEDB.12.0;"
dbs = "Data Source=" & Application.StartupPath & "/POS.accdb"
Using con As OleDbConnection = New OleDbConnection(dbp & dbs)
con.Open()
da = New OleDbDataAdapter("SELECT * FROM tblInventory", con)
da.Fill(dt)
dgList.DataSource = dt
End Using
txtPNum.Focus()
End Sub
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
dt.Clear()
Using con As OleDbConnection = New OleDbConnection(dbp & dbs)
con.Open()
da = New OleDbDataAdapter("SELECT * FROM tblInventory WHERE Prod_Num = #ProdNum", con)
da.SelectCommand.Parameters.AddWithValue("#ProdNum", txtPNum.Text)
da.Fill(dt)
dgList.DataSource = dt
End Using
txtPName = dt.Rows(0).Item(1)
txtNOrder = dt.Rows(0).Item(2)
txtPRem = dt.Rows(0).Item(3)
txtPrice = dt.Rows(0).Item(4)
txtPNum.Focus()
End Sub
I would also recommend adding some Try Catch blocks to handle errors, and you may need to convert the values you're assigning to text boxes if they're something other than String.