VB.Net and SQLite not saving - vb.net

as the title says it's not saving
Code
Try
connection()
Dim cmd As New SQLiteCommand
'cmd.Connection = connection()
cmd.CommandType = CommandType.Text
cmd.CommandText = "UPDATE Emp SET Value = Value +1 WHERE Id='1'"
cmd.ExecuteNonQuery()
cmd.Dispose()
connect.Close()
MsgBox("Data Has been Saved !")
Catch ex As Exception
MsgBox("Failed when saving data")
End Try
Basically im incrementing Log by 1 if the Id is equal to X.
the error seems to be in "cmd.ExecuteNonQuery()"
Table name : Emp
Value = Integer
Id = Integer

Comments and explanations in-line.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Try
'Get your connection locally
Using cn As New SQLiteConnection("Your connection string")
'The using blocks ensure that your database objects are
'closed and disposed even if there is an error.
'You have put your Id in single quotes '1'
'This indicates that it is a string
'Usually an Id is a number, check your database
Using cmd As New SQLiteCommand("UPDATE Emp SET Value = Value +1 WHERE Id='1'", cn)
'You can pass your command text and the connection
'directly to the command constructor
cmd.CommandType = CommandType.Text
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
MsgBox("Data Has been Saved !")
Catch ex As Exception
MsgBox("Failed when saving data. " & ex.Message)
End Try
End Sub
If your ID in your Where clause is not a literal and comes from user input then you need to use parameters.

I don't know if this is a bug or anything... but i created another project then copy and paste everything.
weird thing is it works! but the original one still doesn't. i mean i copy and paste everything from the designer to the code and the copy worker while the original doesn't
I'm using VS 2013 Updated 5...
thank you both of you.

Related

"No value given for one or more required parameters" error using OleDbCommand

I am trying to update a record in MS Access using VB.net. This code will be under the "Delivered" button. When I try to run it, it shows the "No value given for one or more required parameters" error. Here is my code:
Private Const strConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Traicy\Downloads\MWL(11-30-2021)\MadeWithLove\MadeWithLove\MadeWithLove.mdb;"
ReadOnly conn As OleDbConnection = New OleDbConnection(strConn)
Dim cmd As OleDbCommand
Public Sub DeliveredUpdate()
Const SQL As String = "UPDATE DELIVERY SET delivery_status = #status"
cmd = New OleDbCommand(SQL, conn)
' Update parameter
cmd.Parameters.AddWithValue("#status", "Delivered")
' Open connection, update, then close connection
Try
conn.Open()
If cmd.ExecuteNonQuery() > 0 Then
MsgBox("The delivery status was successfully updated.")
End If
conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
conn.Close()
End Try
End Sub
Do not declare connections or commands outside of the method where they are used. These database objects use unmanaged resources. They release these resources in their Dispose methods. The language provides Using blocks to handle this.
As mentioned in comments by Andrew Morton, you should have a Where clause to tell the database which record to update. This would contain the primary key of the record. I guessed at a name for the field, OrderID. Check your database for the real field name.
Access does not use named parameters but you can use names for readability. Access will be able to recognize the parameters as long as they are added to the Parameters collection in the same order that they appear in the sql string. In some databases the Add method is superior to AddWithValue because it doesn't leave the datatype to chance.
It is a good idea to separate your database code from your user interface code. If you want to show a message box in your Catch put the Try blocks in the UI code. This way your function can be used in a web app or mobile app without rewriting.
Public Function DeliveredUpdate(ID As Integer) As Integer
Dim recordsUpdated As Integer
Dim SQL As String = "UPDATE DELIVERY SET delivery_status = #status Where OrderID = #Id;"
Using conn As New OleDbConnection(strConn),
cmd As New OleDbCommand(SQL, conn)
cmd.Parameters.Add("#status", OleDbType.VarChar).Value = "Delivered"
cmd.Parameters.Add("#Id", OleDbType.Integer).Value = ID
conn.Open()
recordsUpdated = cmd.ExecuteNonQuery
End Using 'closes and disposes the command and connection
Return recordsUpdated
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim retVal As Integer
Dim id As Integer = 1 'not sure where you are getting this value from
Try
retVal = DeliveredUpdate(id)
Catch ex As Exception
MsgBox(ex.Message)
End Try
If retVal > 0 Then
MsgBox("The delivery status was successfully updated.")
End If
End Sub

Is there any problem with this code to update database values in MS Access?

My form has a DataGridView on which, if I click on a row, the row details get placed in corresponding controls on the form. Then I can do some changes on these controls and click the button Update. Surprisingly, the code does not do any changes to the database. I am wondering then, is there any problem in this code? Here is the Update button code of my application.
Private Sub UpdateButton_Click(sender As Object, e As EventArgs) Handles updateButton.Click
Try
Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Tukabakoma.mdb;")
conn.Open()
Dim cmd As New OleDbCommand("Update Members set [Name]=#name,Middlename=#midname,Surname=#sname,ContactNumber=#contnum,Address=#address,DOB=#dob,Gender=#gender,[Status]=#status,JoinDate=#jd,POB=#pob,[Guardian Name]=#guardname,[Guardian Surname]=#guardsname,Relationship=#rel,GuardNumber=#gcontnum where TKBS_ID=#tkbsid", conn)
With cmd.Parameters
.AddWithValue("#tkbsid", tkbsIDTextBox.Text)
.AddWithValue("#name", nameTextBox.Text)
.AddWithValue("#midname", middleNameTextBox.Text)
.AddWithValue("#sname", surnameTextBox.Text)
.AddWithValue("#contnum", contactTextBox.Text)
.AddWithValue("#address", addressTextBox.Text)
.AddWithValue("#jd", jdDateTimePicker.Value)
If maleRadioButton.Checked = True Then
.AddWithValue("#gender", maleRadioButton.Text)
ElseIf femaleRadioButton.Checked = True Then
.AddWithValue("#gender", femaleRadioButton.Text)
End If
.AddWithValue("#status", statusComboBox.Text)
.AddWithValue("#dob", dobDateTimePicker.Value)
.AddWithValue("#pob", burialPlaceTextBox.Text)
.AddWithValue("#guardname", gNameTextBox.Text)
.AddWithValue("#guardsname", gSurnameTextBox.Text)
.AddWithValue("#rel", relationshipTextBox.Text)
.AddWithValue("#gcontnum", gNumberTextBox.Text)
End With
cmd.ExecuteNonQuery()
RefreshDataGridView()
MessageBox.Show("Member information successfuly updated!", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information)
cmd.Dispose()
conn.Close()
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, "ERROR12", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
The main idea here for OleDb and Access is to have the parameters added to the Parameters collection in the same order as they appear in the Sql statement.
.AddWithValue("#rel", relationshipTextBox.Text) and .AddWithValue("#gcontnum", gNumberTextBox.Text) are not in your update statement so they can't be added to the parameters collection. If you alter your Update statement to include these be sure to put them in correct spot when adding them to the Parameters collection.
There is no need to close your connection because the End Using line will close and dispose it. It would be better if you did likewise with the OleDbCommand. That is, enclose in a Using block.
Dim cmd As New OleDbCommand(Dim cmd As New OleDbCommand("Update Members set
[Name]=#name,
Middlename=#midname,
Surname=#sname,
ContactNumber=#contnum,
Address=#address,
DOB=#dob,
Gender=#gender,
[Status]=#status,
JoinDate=#jd,
POB=#pob,
[Guardian Name]=#guardname,
[Guardian Surname]=#guardsname,
Relationship=#rel,
GuardNumber=#gcontnum
where TKBS_ID=#tkbsid", conn)
With cmd.Parameters
.AddWithValue("#name", nameTextBox.Text)
.AddWithValue("#midname", middleNameTextBox.Text)
.AddWithValue("#sname", surnameTextBox.Text)
.AddWithValue("#contnum", contactTextBox.Text)
.AddWithValue("#address", addressTextBox.Text)
.AddWithValue("#dob", dobDateTimePicker.Value)
If maleRadioButton.Checked = True Then
.AddWithValue("#gender", maleRadioButton.Text)
ElseIf femaleRadioButton.Checked = True Then
.AddWithValue("#gender", femaleRadioButton.Text)
End If
.AddWithValue("#status", statusComboBox.Text)
.AddWithValue("#jd", jdDateTimePicker.Value)
.AddWithValue("#pob", burialPlaceTextBox.Text)
.AddWithValue("#guardname", gNameTextBox.Text)
.AddWithValue("#guardsname", gSurnameTextBox.Text)
.AddWithValue("#tkbsid", tkbsIDTextBox.Text)
End With
I must mention that .AddWithValue is not the best way to do this. 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
The preferred method is the .Add(parameterName As String, OleDbType As OleDBType, Size As Integer).Value = yourValue

Compare db value with textbox value VB

My Table
I load the windows user name to textbox1.text using 'System.Environment'
After that I query this and compare the textbox value to the PersonName in db
if it matches, I want to get the relevant Department name ie if it's 'manager'
then I want to display a form from menuitem_click event. My code is below
it dosent work can some one please help with this.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Dim cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Dim cmd As New SqlClient.SqlCommand
Dim tbl As New DataTable
Dim da As New SqlClient.SqlDataAdapter
Dim reader As SqlClient.SqlDataReader
Dim ta As String
Try
cn.Open()
Dim sql As String
sql = "select * from dbo.Person where [PersonName] ='" + TextBox1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
While reader.Read
ta = reader.Item("Department")
If ta = 'Maneger' Then
Form2.Show()
End If
' TextBox2.Text = reader.Item("Department")
'TextBox2.Text = reader.Item("dob")
End While
cn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
No matter how you spell it, Manager or Maneger, just make sure what is in the database matches what is in your If statement. I think I would use a drop down box for you to select the Department wherever you are inserting the Person so the Department name would match.
The Using...End Using blocks ensure that you database objects are closed and disposed even if there is an error.
You can pass your Sql statement and the connection directly to the constructor of the command. If all you need is the Department then don't drag down all the date with "*".
Never concatenate strings to build Sql statements. A hacker could type in TextBox1 "Joe; Drop Table dbo.Person;" Using parameters stops this hole because the .Value of the parameter is treated as only a value not executable code.
You are only expecting one value in return so you can use .ExecuteScalar which returns the first column of the first row in the result set.
Your code is very fragile because I suspect you could have duplicate names unless you require unique user names.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Try
Using cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Using cmd As New SqlClient.SqlCommand("Select Department From dbo.Person Where PersonName = #Name;", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text
cn.Open()
Dim ta As String = cmd.ExecuteScalar.ToString
If ta = "Maneger" Then
Form2.Show()
End If
TextBox2.Text = ta
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

The variable name '#userid2' has already been declared. Variable names must be unique within a query batch or stored procedure

This is my first time asking a question here. I am working on a project in which I have to update a table and also insert into another table using a transaction.
The insert part of the transaction block will come from the content of a selected gridview row.
The error I am getting is:
The variable name '#userid2' has already been declared. Variable names must be unique within a query batch or stored procedure.
How can I resolve this error?
This is my code:
Protected Sub btnmodifyaccessdepot_Click(sender As Object, e As EventArgs) Handles btnmodifyaccessdepot.Click
Using con As New SqlConnection(ConString)
con.Open()
Dim sqlTran As SqlTransaction = con.BeginTransaction()
Dim command As SqlCommand = con.CreateCommand()
command.Transaction = sqlTran
Try
command.CommandText = "UPDATE Rhema_TechnicalAccess set Active=#Active,Requester= #Requester,Approver=#Approver,Issuer=#Issuer where userid=#userid"
command.Parameters.AddWithValue("#Active", lblactiveadd.Text)
command.Parameters.AddWithValue("#Requester", lblrequesterAdd.Text)
command.Parameters.AddWithValue("#Approver", lblapproveradd.Text)
command.Parameters.AddWithValue("#Issuer", lblisssueradd.Text)
command.Parameters.AddWithValue("#Userid", lblselecteduserid.Text)
command.ExecuteNonQuery()
For Each row As GridViewRow In gridadddepot.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkdepots As CheckBox = DirectCast(row.FindControl("chkdepots"), CheckBox)
If chkdepots.Checked Then
Dim lbldepot As TextBox = DirectCast(row.FindControl("lbldepot"), TextBox)
command.CommandText = "INSERT INTO Rhema_TechnicalAccessDepot VALUES(#userid2,#Depot,#Access,#TechnicalAccessID)"
command.Parameters.AddWithValue("#userid2", lblselecteduserid.Text)
command.Parameters.AddWithValue("#Depot", lbldepot.text)
command.Parameters.AddWithValue("#Access", lbluseraccessAdd.Text)
command.Parameters.AddWithValue("#technicalaccessid", lbltechnicalaccessid.Text)
End If
End If
Next
command.ExecuteNonQuery()
sqlTran.Commit()
lblmessage2.Text = "Both records were written to database."
Catch ex As Exception
lblmessage2.Text = ex.Message
Try
sqlTran.Rollback()
Catch exRollback As Exception
lblmessage2.Text = exRollback.Message
End Try
End Try
End Using
End Sub

Check before dataser make changes

I use datagridview and populate it using dataset as follows:
Private GetGeschaftDataSet As New DataSet
Public Function GetDataSet() As DataSet Implements IDAL.GetDataSet
Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(System.String)).ToString()
Using con As New SqlConnection(strcon)
Using cmd As New SqlCommand("SELECT * FROM T_Marke", con)
con.Open()
' Create a data adapter in the method and throw it away afterwards
Using GetProjectsDataAdapter = New SqlDataAdapter(cmd)
GetProjectsDataAdapter.Fill(GetGeschaftDataSet, "trial1")
End Using
End Using
End Using
Return GetGeschaftDataSet
End Function
when user ends work with that i save changes to db like this:
Public Sub MakeChangesDataSet() Implements IDAL.MakeChangesDataSet
If Not GetGeschaftDataSet.HasChanges Then
MessageBox.Show("No changes to save", "Informacja", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
Dim i As Integer
Try
Using MyConnection = New SqlConnection(strcon)
Using cmd As New SqlCommand("SELECT * FROM T_Marke", MyConnection)
MyConnection.Open()
' Create a data adapter in the method and throw it away afterwards
Using GetProjectsDataAdapter = New SqlDataAdapter(cmd)
Dim cmdbuilder As New SqlCommandBuilder(GetProjectsDataAdapter)
i = GetProjectsDataAdapter.Update(GetGeschaftDataSet, "trial1")
End Using
End Using
End Using
MessageBox.Show("Updated" & i & " marke", "Informacja", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Sub
However i would like to check whether to not duplicate data, in this case if my table contains columns: Id and Name - i don't want to update if user placed already existing Name. How to achieve that or should i do the check on datagrid level?
There some ways to do this.
Open a connection and select count all rows with that name and if is zero in the same connection execute the insert.
Using a stored procedure which will do all the above.
Create a unique index on Name column
I would use the third.