Why wont my SET value WHERE SQL Statement not work - sql

Currently cant get this to work, despite it being almost for verbatim the same as else where in my code.
Using con As New OleDbConnection(constring)
Using cmd As New OleDbCommand("UPDATE " & "`" & "SIQPERSIST" & "`" & " SET [Date_Added] = #Date_Added WHERE [BatchName] = #BatchName", con)
cmd.Parameters.AddWithValue("#BatchName", BatchName2)
cmd.Parameters.AddWithValue("#Date_Added", Date.Now.ToShortDateString)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
End Using
I'm working in Vb.net
and i need to update all rows that have the name BatchName2 (this comes from a textbox)
with the current date.
The table they are on is SIQPERSIST.
The error i get is that its missing a parameter.
But i have don't know what parameter it needs despite almost similar code working else where, except the working code uses a WHERE KEY= 'keynumber' statement.

The issue is this uses backticks for the concatenated variable. Remember, ` and ' are not the same thing, and only one of those would work here.
It should look like something more like this:
Using con As New OleDbConnection(constring)
Using cmd As New OleDbCommand("UPDATE SIQPERSIST SET [Date_Added] = Date() WHERE [BatchName] = #BatchName", con)
cmd.Parameters.AddWithValue("#BatchName", BatchName2)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Note, there's no need to call con.Close() when you have a Using block to take care of that for you.
Additionally, not only did I convert BatchName2 to a real query parameter (Shame on you for adding concatenation to a query that already demonstrates how to use parameters!), but I was also able to convert the existing parameter to use get the date in the DB itself.

Related

Parameterized SQL Command does not update my column

I have a simple button which end the Work day in my Management System. Sadly when pressed all fine but the Column in my Table is still empty.
Here is the code:
Dim sql As String = "UPDATE [TA-Arbeitszeit] SET Ende = #ende WHERE Personal_nr = #Personal_nr"
Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\recycle2000.mdb;"),
cmd As New OleDbCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("#Personal_nr", OleDbType.VarChar).Value = tbxUserInput.Text.Trim()
cmd.Parameters.Add("#ende", OleDbType.VarChar).Value = DateTime.Now.ToString("G")
Dim icount As Integer = cmd.ExecuteNonQuery
End Using
Access doesn't fully support named parameters. Although you can and should use parameter names for your own clarity, Access ignores them. It simply inserts your parameter values into the SQL code in the order they are added. That means that they need to be added in the same order as they appear in the SQL code. Your SQL code has #ende before #Personal_nr but when you add parameters you do it the other way around. Switch the order in which you add the parameters and you should hopefully be fine.

'No value given for one or more required parameters.' Error, Can't get over it

I'm trying to take a Yes/No value from my database on Access and make it so if the Yes/No is checked on Access it will check it on the form. Although I keep getting
System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.'
On the line Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
Sorry if it's a really easy and stupid mistake, I'm a college student and googling isn't helping me figure this one out.
cn.Open()
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
While rs.Read
Dim DisplayValue As String = rs("staffIn")
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
SQLCmd.ExecuteNonQuery()
End While
cn.Close()
I know this is an old post but I seem to remember that OleDb does not support named parameters.
Also, pretty sure that DarrenSloan should be surrounded by single quotes, like any string value. And indeed, reusing the SQL command like this is not the way to do it.
The CommandText:
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
does not contain any parameter.
Thus, the parameter inorout has no effect:
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
Either use two statements, one SELECT and one UPDATE.
Or use a different mechanism like a databound grid. Maybe you are using a datagridview control to display the data. Then there are different techniques to keep the data in sync. It depends on how you choose to render the data on your form.
Firstly, get rid of the loop. You would only use a loop if you were expecting more than one record. By the looks of it, you are expecting only one record, so no loop.
Secondly, stop calling ExecuteNonQuery. That is for making changes to the database, which you're obviously not trying to do. You obviously know how to get data from the query because you're doing it here:
Dim DisplayValue As String = rs("staffIn")
If you want to get data from another field, do the same thing. You can then use that data in whatever way you like, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = 'DarrenSloan'", connection)
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using
Notice that I have wrapped the text literal in the SQL in single-quotes? I would expect that you would normally not want to hard-code a name there, but use input from the user instead, In that case, you would use a parameter, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = #staffName", connection)
command.Parameters.Add("#staffName", OleDbType.VarChar, 50).Value = staffNameTextBox.Text
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using

VB Access DB Update statement

I am new to this forum, please could you help me get this code to work, when i execute it, it simply does nothing and does not update the DB. If i remove the square brackets it gives an error: "SYNTAX ERROR in UPDATE statement"
Any help appreciated!
Dim connection As OleDbConnection
connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=UserDB.accdb;Jet OLEDB:Database;")
connection.Open()
Dim pass As String
pass = txtconfirm.Text
Dim user As String
user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= '" & pass & "' WHERE [Username]= '" & user & "';"
Dim command As New OleDbCommand(query, connection)
command.ExecuteNonQuery()
connection.Close()
Given your actual connection string, the database that will be updated is the one in the directory where your application starts. This means that if you work with a WinForms application this folder is \BIN\DEBUG or x86 variant. If there is not error then you could get the return value of the ExecuteNonQuery call to verify if a record has been updated or not
Dim rowsUpdated = command.ExecuteNonQuery()
MessageBox.Show("Record updated count = " & rowsUpdated)
If this value is not zero then your database has been updated and you are looking for changes in the wrong database. Check the one in the BIN\DEBUG folder.
In any case your code has big problems. If your variables user or pass contain a single quote, then your code will crash again because your string concatenation will form an invalid SQL. As usual the only workaround is to use a parameterized query
Dim pass = txtconfirm.Text
Dim user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= #p1 WHERE [Username]= #p2"
Using connection = New OleDbConnection("...........")
Using command As New OleDbCommand(query, connection)
connection.Open()
command.Parameters.Add("#p1", OleDbType.VarWChar).Value = pass
command.Parameters.Add("#p2", OleDbType.VarWChar).Value = user
command.ExecuteNonQuery()
End Using
End Using
The parameterized approach has many advantages. Your query text is more readable, there is no misunderstanding between your code and the values expected by your database engine. And while not easy to exploit with MS-Access there is no problem with Sql Injection
I think Steve presents a much better approach for you coding this...
Let me just throw out a few more things:
The reason you can't take those brackets out is some of your column names are reserved words; just FYI.
Since you report "it does nothing..." when you execute, it sounds like you have a valid connection and sql syntax, in which case my next step would be to copy the sql command text while in debug mode, change it to a select and run it in your DB. You should get one result when you do. If not, either your criteria or field contents are not what you think they are...
Just change the Update table SET field-value ... to SELECT * FROM table and leave the WHERE clause as is.

Using DataReader in VB.NET

I got the error message There is an open data reader associated with this command which needs to be closed first by using the following code:
myCommand = New SqlCommand("SELECT BookCode FROM tblBook",myConnection)
myReader = myCommand.ExceuteReader
While myReader.Read
If myReader(0).ToString <> txtBookCode.Text Then
myCommand = New SqlCommand("INSERT INTO tblBook VALUES(#BookCode, #BookTitle)",myConnection)
myCommand.Parameters.AddWithValue("#BookCode", txtBookCode.Text)
myCommand.Parameters.AddWithValue("#BookTitle", txtBookTitle.Text)
myCommand.ExecuteNonQuery()
Else
MsgBox("There is already a book name '"& txtTitle.Text "'. Please try another code.",vbOkOnly,"BookCode Exists")
End If
End While
Pleas help.
Don't reuse myCommand variable. Create new one.
myCommand should be disposed in the end too (as well as reader).
Real reason of exception is more likely that you're trying to run two command on one connection at the same time.
First read all data you need from reader and THEN do all inserts. Not both at once (i assume you don't want to create two connections. That would suck)
looks like you're trying to use one variable myCommand more than once - in the first line of code and within a WHILE loop.
it's better to declare one more AdoCommand variable to use it in LOOP

External database path as parameter for parametrized query to Access

I'm writing small VB.Net app which should build reports based on data gathered from some external MDB-files (Access 2007). It was planned that this app will use parametrized SQL queries to collect data. One of the parameters for these queries is path to the external MDB-file.
Here goes sample code:
Dim conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=C:\Temp\Temp.mdb;")
conn.Open()
Dim cmd As New OleDbCommand()
cmd.Connection = conn
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT * INTO Trend FROM TI IN '?' WHERE TI.Id=?;"
With cmd.Parameters
.Add("#p1", OleDbType.VarChar).Value = "C:\Temp\Source.mdb"
.Add("#p2", OleDbType.Integer).Value = 5
End With
cmd.ExecuteNonQuery()
conn.Close()
Looks simple but it doesn't works. After launch my app throws following exception - System.Data.OleDb.OleDbException: Disk or network error.
Have spent a whole day to make it work with no success. What have I done wrong?
This is a comment that others have suggested is the answer to the question:
Nothing in an Access/Jet/ACE FROM clause is parameterizable (unless it's inside a subquery, of course).
With Access/Jet/ACE your only choice is to use some other method to write the FROM clause on-the-fly.