VB SQL DELETE Statement Not Working - No Error At All - sql

This is my Code and it just doesn't work, I'm trying to make it Delete a record where the column staffID is equal to the variable currentStaffID although it doesn't delete the record or give an error, it just carries on and displays the MsgBox after the DELETE Statement.
Dim AreYouSureEdit = MsgBox("Are you sure you want to delete this record?", MsgBoxStyle.YesNo)
If DbConnect() And AreYouSureEdit = MsgBoxResult.Yes Then
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
currentStaffID = editStaffIDTxtBox.Text()
SQLCmd.CommandText = "DELETE * STAFF WHERE staffID = #currentStaffID"
cn.Close()
MsgBox("Record Deleted.", MsgBoxStyle.OkOnly)
End If

You're setting up your command and everything - but you're never executing it! Of course nothing happens.....
You need to add one line of code:
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
currentStaffID = editStaffIDTxtBox.Text()
SQLCmd.CommandText = "DELETE * STAFF WHERE staffID = ?"
'' You need to define the parameter and set its value here!
SQLCmd.Parameters.Add("p1", OleDbType.Int).Value = currentStaffID;
'' you need to actually **EXECUTE** your DELETE query!
SQLCmd.ExecuteNonQuery()
cn.Close()
Also, while you're setting up a parameter in your SQL query text just fine, I don't see where you're actually defining such a parameter on your SQLCmd object - and also be aware: OleDB doesn't use named parameters (like the native SQL Server client does) - it uses positional parameters (so that's what I replaced your named parameter with just a ?). Since there's only one parameter, this shouldn't be a problem here - but you need to properly define the SQLCmd's parameter (and set its value)

Connections and Commands can use unmanaged resources so, they need to have their .Dipose methods called to release these resources. Using...End Using blocks take care of this and also .Close the connection. Your database objects must be local to the method where they are used for this to work.
Always use Parameters to avoid Sql injection.
Private Sub OpCode()
Dim AreYouSureEdit = MsgBox("Are you sure you want to delete this record?", MsgBoxStyle.YesNo)
If AreYouSureEdit = MsgBoxResult.Yes Then
Using cn As New OleDbConnection("Your connection string"),
SQLCmd As New OleDbCommand("DELETE From STAFF WHERE staffID = #currentStaffID", cn)
SQLCmd.Parameters.Add("#currentStaffID", OleDbType.Integer).Value = CInt(editStaffIDTxtBox.Text)
cn.Open()
SQLCmd.ExecuteNonQuery()
End Using
MsgBox("Record Deleted.", MsgBoxStyle.OkOnly)
End If
End Sub

Related

How to delete a row in sql using vb.net

Sorry if its easy or basic i am brand new to sql and tables so im just trying to figure it out
Basically im trying to delete a row that the user selects
By having them click on a row then clicking a delete button but i don't know how that should look ive tried a few different ways but none of them seem to work.
No error comes up but it just dosen't delete the row
Private Sub DeleteSelectedUsers()
Dim connection As SqlConnection = New SqlConnection()
connection.ConnectionString = "Data Source=GERARD-PC\SQLEXPRESS; Initial Catalog=TestDB;User ID=AccountsUser;Password=password123"
connection.Open()
Dim adp As SqlDataAdapter = New SqlDataAdapter _
("Delete * from dgrdUsers.SelectedRows(0).Cells", connection)
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Try
Dim username As String = dgrdUsers.SelectedRows(0).Cells.Item("Username").Value.ToString()
If (MessageBox.Show(Me, "Do you want to delete user " & username & "?", "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
DeleteSelectedUsers()
End If
Catch ex As Exception
End Try
End Sub
Any ideas?
The syntax required to delete a row in the database table requires at least three parts.
The DELETE command
The FROM statement to identify the table where the delete action should occur
The WHERE condition to identify the record (or records) to delete
So it is a string like this: DELETE FROM tablename WHERE condition
and applied to your code you get this.
Private Sub DeleteSelectedUsers(userName as String)
Using connection As SqlConnection = New SqlConnection()
connection.ConnectionString = "...."
connection.Open()
Dim cmd As SqlCommand = New SqlCommand _
("DELETE FROM Table WHERE userName = #user", connection)
cmd.Parameters.Add("#user", SqlDbType.NVarChar).Value = userName
cmd.ExecuteNonQuery()
End Using
End Sub
(Table and UserName are fantasy names because we don't know what is the actual schema of your database)
Other things I have changed:
The connection is created inside a using block to be sure a proper
closure and dispose happens even in case of errors
The name of the user to remove should be passed as parameter to the
function
No need to use an adapter when you just need to execute a single
SqlCommand
The query doesn't concatenate strings to build the command but use a
parameter added to the command itself and specifying a type for the
data matching the type on the database table

"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

Incorrect syntax near 'NO'.' in vb.net on cmd.ExecuteNonQuery()

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
cmd = con.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "update Tabledb set FIRSTNAME=" & TextBox1.Text & ",LASTNAME=" & TextBox2.Text & ",PHONE NO=" & TextBox3.Text & ", where Id =" & i & ""
cmd.ExecuteNonQuery()
cmd.Connection = con
disp_data()
End Sub
Give you controls meaningful names. This will make your coding much easier. I have renamed your controls as an example.
You should not have to check ConnectionState. Connections, commands and other database objects use unmanaged resources. To release these they provide a Dispose method which must be called. These objects should be declared locally in the method where they are used. vb.net provides Using...End Using blocks where you declare connections, commands etc. The block will dispose the objects at the End Using. (It will also Close the connection which you failed to do.)
Don't Open the connection until directly before the .Execute....
You can pass the the connection string directly to the connection's constructor. Your can pass the CommandText and the Connection directly to the constructor of the command.
It is useless to set the Connection property of the command after you have attempted to execute the command.
CommandType.Text is the default so it is not necessary to set this property explicitly.
NEVER concatenate strings to build Sql statements.
ALWAYS use parameters.
The field names you use in you Sql string must match exactly the names in the database. That means upper case, lower case, spaces, and periods. If a field name is a reserved word, contains a space or other unusual character is needs to be surrounded by identifier delimiters. For Access and Sql Server that would be brackets [ ]. For MySql use the back tick `. On my USA keyboard that is found below the tilde in the upper left corner. If you are not sure if you need the delimiters you can use them anyway. It won't hurt anything.
I had to guess at the datatypes of the parameters. Check the database for the actual types. I also guessed at the database. Change the code to OleDb for Access and MySql for MySql.
Private OPConStr As String = "Your connection string."
Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Dim i As Integer = 5 'I made up a value, don't know where this comes from in the real code
Dim strSql = "update Tabledb set FIRSTNAME = #FirstName, LASTNAME = #LastName, [PHONENO.] = #Phone, where Id = #ID;"
Using con As New SqlConnection(OPConStr),
cmd As New SqlCommand(strSql, con)
cmd.Parameters.Add("#FirstName", SqlDbType.NVarChar).Value = txtFirstName.Text
cmd.Parameters.Add("#LastName", SqlDbType.NVarChar).Value = txtLastName.Text
cmd.Parameters.Add("#Phone", SqlDbType.VarChar).Value = txtPhone.Text
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = i
con.Open()
cmd.ExecuteNonQuery()
End Using
disp_data()
End Sub

Self learning on vb.net

Currently I'm trying to understand and learn new code commands for vb.net. i have came across three codes while researching which is
"SELECT staff_id,pass_word FROM userlogin WHERE staff_id = #staff_id AND pass_word = #pass_word")
Second code:
Dim uName As New OleDbParameter("#staff_id", SqlDbType.VarChar)
Third and last:
uName.Value = txtstaffid.Text
myCommand.Parameters.Add(uName)
What are the uses of #pass_word code when you have already typed the pass_word column, Oledbparameter, and Parameters.Add?
The following code shows a bit more complete picture of what the code is doing. The Using...End Using blocks ensure that your objects are closed and disposed even if there are errors. Of course, in a real application, passwords would never be stored as plain text (too easy to hack). They would be salted and hashed but that is for another day.
Private Sub CheckPassword()
'This line assigns a Transact SQL command to a string variable.
'It will return a record with 2 columns. The #staff_id and #pass_word are parameter placeholders.
'The use of parameters limits the possibilit of SQL injection with malicious input be the user
'typing in the text box.
Dim strSQL = "SELECT staff_id,pass_word FROM userlogin WHERE staff_id = #staff_id AND pass_word = #pass_word;"
Using cn As New SqlConnection("Your connection string")
'Pass the command string and the connection to the constructor of the command.
Using cmd As New SqlCommand(strSQL, cn)
'It is unneccessary to create a command variable.
'The .Add method of the commands Parameters collection will create a parameter.
cmd.Parameters.Add("#staff_id", SqlDbType.VarChar).Value = txtstaffid.Text
cmd.Parameters.Add("#pass_word", SqlDbType.VarChar).Value = txtPassword.Text
cn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader
'All we really need to know is whether we returned a row.
If dr.HasRows Then
MessageBox.Show("Login Successful")
Else
MessageBox.Show("Login Failed")
End If
End Using
End Using
End Using
End Sub

I get "Syntax error in UPDATE statement" with OleDB

I am developing an information system that works with a connected data source / MS Access database. The question is kinda cliche but I can't seem to find a proper solution from the similar ones I have come across.
Here is my code for the button.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'myConnection.ConnectionString = connString
'myConnection.Open()
If Me.txtConfirmPasscode.Text = Me.txtNewPasscode.Text Then
Dim updateCmd As OleDbCommand = New OleDbCommand("UPDATE Users SET Password = #ConfPasscode WHERE [Usernames] = #UsersID", myConnection)
Dim dr2 As OleDbDataReader = updateCmd.ExecuteReader 'SYNTEX ERROR IN UPDATE STATEMENT
With updateCmd.Parameters
updateCmd.Parameters.AddWithValue("#value", txtUserID.Text)
updateCmd.Parameters.AddWithValue("#firstname", txtConfirmPasscode.Text)
End With
updateCmd.ExecuteNonQuery()
Dim recFound As Boolean = False
Dim UserName As String = ""
While dr2.Read
recFound = True
UserName = dr2("Usernames").ToString
End While
If recFound = True Then
MessageBox.Show("Password changed successfully for " & UserName & ".", "Password Changed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
'updateCmd.Parameters.Add(New OleDbParameter("Password", CType(txtConfirmPasscode.Text, String)))
Else
myConnection.Close()
Me.Refresh()
End If
Else
End If
Try
myConnection.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
I get a huge UPDATE statement syntax error when I reach these lines of code:
Dim updateCmd As OleDbCommand = New OleDbCommand("UPDATE Users SET Password = #ConfPasscode WHERE [Usernames] = #UsersID", myConnection)
Dim dr2 As OleDbDataReader = updateCmd.ExecuteReader 'I GET THE SYNTAX ERROR IN UPDATE STATEMENT ERROR HERE!
I hope that I can get a solution that works without overly formatting the code. I would also like to get solutions to my code grammer / syntax that could possibly cause some other problems in the above code
Password is a reserved keyword in ms-access. You need square brackets around it, but then you have another problem. You should set the parameters BEFORE executing the query, and albeit OleDb doesn't recognize parameters by name but by position, giving a matching name with your placeholders doesn't hurt
Dim updateCmd As OleDbCommand = New OleDbCommand("UPDATE Users
SET [Password] = #ConfPasscode
WHERE [Usernames] = #UsersID", myConnection)
With updateCmd.Parameters
' First ConfPasscode because is the first placeholder in the query
updateCmd.Parameters.AddWithValue("#ConfPasscode ", txtConfirmPasscode.Text)
' Now UsersID as second parameter following the placeholder sequence
updateCmd.Parameters.AddWithValue("#UsersID", txtUserID.Text)
End With
Dim rowUpdated = updateCmd.ExecuteNonQuery
....
In response to the comment below of Andrew Morton, I should mention to the problems caused by AddWithValue. In this context, with just strings, it is a performance problem, in other context (dates and decimals) could escalate to a correctness problem.
References
Can we stop to use AddWithValue already?
How data access code affects database performance
Also, as noted in another answer, the correct method to use for an Update query is ExecuteNonQuery, but also ExecuteReader can update your table but because it build an infrastructure required only when you have something to read is less efficient for an Update. In any case just use only ExecuteNonQuery or ExecuteReader
I notice that your execute your UPDATE command using executereader. It means that you will be returning a record after the update. On your query it only trigger update query. Maybe try putting it on stored procedure and selecting the updated records after the changes made.