datatypes dont match, correct query and table - vb.net

Got a new one for you, tried everything i could think of but without succes.
I want to be able to edit some textboxes and then update their records in the database. I use this code:
Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
connection.Open()
cmdupdate.CommandText = "UPDATE tbl_stal SET Locatie = '" & cbLocatienummer.Text & "', Coordinaten = '" & txtCoordinaten.Text & "' WHERE ID = '" & cbID.Text & "'"
cmdupdate.CommandType = CommandType.Text
cmdupdate.Connection = connection
cmdupdate.ExecuteNonQuery()
MsgBox("De gegevens zijn aangepast." & vbNewLine & "The data has been modified." & vbNewLine & "Die Daten sind angepasst.", MsgBoxStyle.OkOnly, "Voersoorten")
connection.Close()
cmdupdate.Dispose()
I am certain that the names of the database table and it's fields are correct, tried using both numerical and textbased settings on the table fields(as normally they should be numerical, but they might be text too. )
However, when i load some data from the datagridvieuw into the textboxes, change the coordinates(for example) and hit the updatebutton, it will give me the error that the datatypes don't match.
Apart from the above, what else can it be?

When you write data to a database table using any kind of sql text you should NEVER use string concatenation to build the SQL. This because you could have problems in the string supplied (what if one of these strings contains an embedded single quote?) and because taking the user input and attaching it to your command is a really dangerous practice that leads to Sql Injection
(Well MS-Access doesn't support multiple commands so you are a bit safer here)
So you should rewrite your query in this way
Dim cmdText = "UPDATE tbl_stal SET Locatie = ?, Coordinaten = ? WHERE ID = ?"
Using connection = new OleDbConnection(.....)
Using cmdUpdate = new OleDbCommand(cmdText, connection)
connection.Open()
cmdUpdate.Parameters.AddWithValue("#p1", cbLocatienummer.Text)
cmdUpdate.Parameters.AddWithValue("#p2", txtCoordinaten.Text)
cmdUpdate.Parameters.AddWithValue("#p3", Convert.ToInt32(cbID.Text))
cmdUpdate.ExecuteNonQuery()
End Using
End Using
Notice that you should provide a parameter with the exact datatype that matches the datatype of your field, strings for text fields, numbers for numeric fields.

Related

syntax error in insert into statement on access and vb.net [duplicate]

This question already has answers here:
vb.net escape reserved keywords in sql statement
(2 answers)
Closed 5 years ago.
Im having a error but i dont know what part but i check my tables but it is the exact column im using ms access2010 as database and every time i add a new record theres a msgbox that show (syntax error in insert into statement) heres my code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub
Private Sub GroupBox1_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GroupBox1.Enter
End Sub
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim add As String = "insert into setplan(ma,planqty,side,start,end,total,remarks) values ('" & cmbshift.SelectedItem & "','" & txtplqty.Value & "','" & cmbside.SelectedItem & "','" & timestart.Text & "','" & timeend.Text & "','" & txttotal.Text & "','" & txtrem.Text & "')"
Dim connection As String = "Provider=Microsoft.Ace.Oledb.12.0; Data Source=C:\Users\Administrator\Documents\plan.mdb; Persist Security Info=False;"
Using conn As New OleDb.OleDbConnection(connection)
Try
conn.Open()
If cmbshift.SelectedItem = "" Then
MsgBox("Please Select Shift Schedule")
ElseIf txtplqty.Value = 0 Then
MsgBox("Please Input Plan Quantity")
ElseIf cmbside.SelectedItem = "" Then
MsgBox("Please select Side")
ElseIf timestart.Text = "" Then
MsgBox("Please Select A Start Time")
ElseIf timeend.Text = "" Then
MsgBox("Please Select A Start Time")
ElseIf timeend.Text = timestart.Text Then
MsgBox("Time end must not be equal to Time Start")
Else
MsgBox(add)
Dim cmd As New OleDb.OleDbCommand(add, conn)
cmd.ExecuteNonQuery()
MsgBox("New Schedule Added")
End If
conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Sub
Private Sub timestart_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timestart.ValueChanged
End Sub
End Class
start and end words are unique for sql so those keywords might cause the problem. Try to switch those column names into something like startTime and endTime and check if that works.
As has been addressed in the comments, it would be much better if you were to make this a parameterized query instead of concatenating the strings into an explicit SQL command. That being said, however, using your example, there are a couple of things that could be causing the error you describe, some of which have been mentioned in the comments (and the answer from Atilla).
Start and End are reserved keywords in SQL. Using them as column names can cause unexpected behavior when executing a query against those columns from a .NET application through OleDb. There are basically two ways to get around this:
Rename these columns in the database - Atilla suggested StartTime and EndTime, which would probably work nicely.
If renaming the columns is not an option (these columns are used by some other system/process you have in place), your best bet is to modify the query. Since it appears that you're working with an Access database (.mdb) file, you can enclose the column names in your query in square brackets (e.g., [Start] and [End]).
I've actually taken to enclosing all of my table and column names this way when working with Access databases because we have some databases with column names that include spaces and such, so this helps tremendously.
You also need to take into account the actual data types of the columns into which you're attempting to INSERT the data. Again, since it seems that you're using an Access database file, there are a couple of syntactical things to look at.
Values being inserted into a Date/Time field should be wrapped with the # character instead of the ' character.
Numeric field types (e.g., Number or Currency) should not be wrapped with the ' character (or any other characters, for that matter).
If the string values you intend to insert into text fields (e.g., Short Text or Long Text) contain any of a number of "special/invalid characters" including single and/or double quotation marks, these need to be "cleaned up" before executing the query. If this is the case (or potentially could be the case), you could create a method to clean up the string value prior to use in your SQL command. See an example at the bottom of this post in which most, if not all of the potentially invalid characters are simply stripped from the string value.
Please note that, for the purposes of this answer, I've used the data type names from the MS Access UI rather than the actual OleDb/Odbc data types to try to simplify things.
Without knowing the actual data types used in your database table or the values that are coming from the form controls, I can only make assumptions, but, if I absolutely had to use this type of query building (meaning, it's not possible to make it parameterized for some reason), I would probably create the query to looks something more like this:
Dim add As String = "INSERT INTO setplan " & _
"([ma], [planqty], [side], [start], [end], [total], [remarks]) " & _
"VALUES ('" & cmbshift.SelectedItem & "', " & _
txtplqty.Value & ", " & _
"'" & cmbside.SelectedItem & "', " & _
"#" & timestart.Text & "#, " & _
"#" & timeend.Text & "#, " & _
txttotal.Text & ", " & _
"'" & txtrem.Text & "')"
This assumes that the [start] and [end] columns are Date/Time columns, and the [planqty] and [total] columns are some type of Number columns (Integer, Single, etc.).
HOWEVER: as mentioned above, it would be much preferred to make this a parameterized query. Check out the accepted answer to this SO question for more information on how to do this: VB.Net - Inserting data to Access Database using OleDb
Example of cleanup function for String values when concatenating SQL command:
Friend Function CleanStringForSQL(ByVal DirtyString As String) As String
Dim CleanString As String = DirtyString.Replace("'", "")
CleanString = CleanString.Replace("""", "")
CleanString = CleanString.Replace("*", "")
CleanString = CleanString.Replace("\", "")
CleanString = CleanString.Replace("/", "")
CleanString = CleanString.Replace(";", "")
CleanString = CleanString.Replace("%", "")
CleanString = CleanString.Replace("#", "")
CleanString = CleanString.Replace("(", "")
CleanString = CleanString.Replace(")", "")
CleanString = CleanString.Replace("[", "")
CleanString = CleanString.Replace("]", "")
Return CleanString
End Function
Which could then be used in your declaration statement for the SQL command string like:
...
"VALUES ('" & CleanStringForSQL(cmbshift.SelectedItem) & "', " & _
...

How do I update a specific row in access using SQL update? In my current code I keep getting the error data type mismatch

In my current code, I keep getting the error data type mismatch most of it worked before I added the SQL where statement to select a specific id
Private Sub UpdateButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpdateButton.Click
'tells your program the data source
provider = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" 'refrences to the provider
datafile = "C:\Users\Abdulaleem\Documents\Books.accdb" 'refers to the location of the file
connectstring = provider & datafile ' combines the 2 variables
myconnect.ConnectionString = connectstring ' this class allows you to connect to the database
myconnect.Open() ' opens the databse
Dim sqlupdate As String
sqlupdate = "Update BooksTbl set BookName='" & TitleTEXT.Text & "' , [BookAuthor]='" & AuthorTEXT.Text & "',[Genre] ='" & GenreTEXT.Text & "',[IsAvailable] = " & status & ",[DatePublished] = '" & DateTimeCHANGER.Text & "' , [PictureLocation] = '" & PiclocTEXT.Text & "' WHERE [ID] = '" & idshower.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(sqlupdate, myconnect) 'creating new database object
Try
cmd.ExecuteNonQuery() ' executes our sql query
cmd.Dispose() 'deleting from ram to stop interferences
myconnect.Close() 'closes database and connection
TitleTEXT.Clear()
AuthorTEXT.Clear()
GenreTEXT.Clear()
Catch ex As Exception ' if the programs crashes then it will be caught here and put into the ex variable
MsgBox(ex.Message) ' shows what error occured
myconnect.Close()
End Try
myconnect.Close()
Assuming that your [ID] column is an integer, try changing it from:
...WHERE [ID] = '" & idshower.Text & "'"
to
...WHERE [ID] = " & idshower.Text
In access, attempting to compare a number with a string results in the message "Data type mismatch in criteria expression".
Note: Unless you are certain the idshower.text actually contains a number, it'd be good practice to check this before executing the query, or access will think you're trying to use a parameter.
Also: You might want to look into parameterised queries which, although they usually result in more lines of code, protect you against things like SQL injection attacks and can perform some basic type conversion for you.

OleDbException was unhandled.......Syntax error in UPDATE statement

I get that Error when i debug please can someone help please...
Below is the code:
Private Sub UpdateToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpdateToolStripMenuItem.Click
If MsgBox("Save Changes?", MsgBoxStyle.Question + MsgBoxStyle.YesNo, "WARNING") = MsgBoxResult.Yes Then
Dim oleDC As New OleDbCommand
With oleDC
.Connection = conn
.CommandText = "UPDATE tblPatientsRecord SET Names='" & txtNames.Text & _
"',Licensenumber='" & txtLicensenumber.Text & _
"',Address='" & txtAddress.Text & _
"',Fullname='" & txtFullname.Text & _
"',Birthday='" & txtBase.Text &
"',Age='" & txtAge.Text & _
"',Country='" & cmbCountry.Text & "' WHERE PatientID='" & txtPatientID.Text & "'"
.ExecuteNonQuery()
MsgBox("Record Updated!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "SUCCESS")
Disable()
Clear()
SaveToolStripMenuItem.Enabled = False
NewToolStripMenuItem.Enabled = True
LoadPatientsRecord()
getLastPatientID()
End With
End If
End Sub
help please
You should use SQL parameters. These will not only simplify your code, they will make certain kinds of errors regarding syntax and data types extremely unlikely and protect against SQL injection attacks:
Dim sql = <sql>
UPDATE tblPatientsRecord SET [Names] = #p1,
Licensenumber = #p2,
Address = #p3,
Fullname = #p4,
Birthday = #p5,
[Age] = #p6,
Country = #p7
WHERE PatientID = #p8
</sql>.Value
Using conn = New OleDbConnection(myConnStr),
cmd As New OleDbCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("#p1", OleDbType.VarChar).Value = txtNames.Text
cmd.Parameters.Add("#p2", OleDbType.VarChar).Value = txtLicensenumber.Text
' ...etc
cmd.Parameters.Add("#p6", OleDbType.Integer).Value = intVar
cmd.Parameters.Add("#p7", OleDbType.VarChar).Value = strVar
'the last one is the WHERE
cmd.Parameters.Add("#p8", OleDbType.VarChar).Value = Convert.ToInt32(lblPatientID.Text)
cmd.ExecuteNonQuery()
'... etc
End Using
There are several other commonly seen issues which should be tended to.
DBConnection objects are intended to be created, used and disposed of rather than the same one used over and over. However, you can use a global connection string so you don't have the same connection string all over the place.
Many of the DBObjects should be disposed of. Using blocks will close and dispose of the connection and command objects. Generally, if something has Dispose method, wrap them in a Using block. The above shows how to "stack" 2 objects (OleDbConnection and OleDbCommand) into one Using statement which reduces indentation.
Use the Add method rather than AddWithValue. This allows you to specify the datataype for each parameter. Without it, the DB Provider must guess which can result in Datatype mismatch or even corrupt the database in some instances.
The WHERE clause is just another parameter. Often people will use Parameters for the first part of the SQL but concatenate for the WHERE clause needlessly.
The above also uses an XML literal to construct the SQL. This is handy for long, complex SQL because you can format and indent it as you like. You can also just use multiple lines to make it readable :
Dim sql = "UPDATE tblPatientsRecord SET [Names] = #p1, " _
& "Licensenumber = #p2, " _
& "Address = #p3, "
If you use SQL reserved words or spaces in table or column names, you must escape the names using [Square Brackets] as shown. It is best not to use either in the names. User, Password Names and Values are commonly seen words used as column or table names which result in SQL syntax errors.
Ticks are not all-purpose SQL field delimiters, they actually indicate that the value being passed is string/text: & "Age ='" & txtAge.Text & "'". If the DB is set to store Age as a number, your SQL is passing it as text/string which can result in a data type mismatch. The same is true of PatientID and Birthday if it is a date field.
A common problem concatenating strings for a SQL statements is too many or too few ticks (') in the result. This cant happen with SQL Parameters.
The main purpose for SQL Parameters, though is to prevent an error if the name is "O'Brian" or "O'Reilly" or "Bobby';DROP TABLE tblPatientsRecord"
These principles apply for other DB providers such asMySql, SQLite and SQLServer. The details such as the exact escape character however will vary.
Note that Access/OleDB doesn't actually use named parameters as such (#FirstName or even #p2), so will often see params in the form of "?". This means that you must add the parameter values (Add/AddWithValue) in the same exact order as those columns appear in the SQL.
For more information see:
Using Statement
Connection Pooling

how to check duplicate record before insert, using vb.net and sql?

can someone help me with my code, i need to check first if record exist. Well i actually passed that one, but when it comes to inserting new record. im getting the error "There is already an open DataReader associated with this Command which must be closed first." can some help me with this? thanks.
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim reg_con As SqlConnection
Dim reg_cmd, chk_cmd As SqlCommand
Dim checker As SqlDataReader
Dim ID As Integer
Dim fname_, mname_, lname_, gender_, emailadd_, college_, password_ As String
ID = idnumber.Value
fname_ = fname.Value.ToString
mname_ = mname.Value.ToString
lname_ = lname.Value.ToString
gender_ = gender.Value.ToString
college_ = college.Value.ToString
emailadd_ = emailadd.Value.ToString
password_ = reg_password.Value.ToString
reg_con = New SqlConnection("Data Source=JOSH_FLYHEIGHT;Initial Catalog=QceandCceEvaluationSystemDatabase;Integrated Security=True")
reg_con.Open()
chk_cmd = New SqlCommand("SELECT IDnumber FROM UsersInfo WHERE IDnumber = '" & ID & "'", reg_con)
checker = chk_cmd.ExecuteReader(CommandBehavior.CloseConnection)
If checker.HasRows Then
MsgBox("Useralreadyexist")
Else
reg_cmd = New SqlCommand("INSERT INTO UsersInfo([IDnumber], [Fname], [Mname], [Lname], [Gender], [Emailadd], [College], [Password]) VALUES ('" & ID & "', '" & fname_ & "', '" & mname_ & "', '" & lname_ & "', '" & gender_ & "', '" & emailadd_ & "', '" & college_ & "', '" & password_ & "')", reg_con)
reg_cmd.ExecuteNonQuery()
End If
reg_con.Close()
End Sub
Add this string to your connection string
...MultipleActiveResultSets=True;";
Starting from Sql Server version 2005, this string allows an application to maintain multiple active statements on a single connection. Without it, until you close the SqlDataReader you cannot emit another command on the same connection used by the reader.
Apart from that, you insert statement is very dangerous because you use string concatenation. This is a well known code weakness that could result in an easy Sql Injection vulnerability
You should use a parameterized query (both for the insert and for the record check)
reg_cmd = New SqlCommand("INSERT INTO UsersInfo([IDnumber], ......) VALUES (" & _
"#id, ......)", reg_con)
reg_cmd.Parameters.AddWithValue("#id", ID)
.... add the other parameters required by the other field to insert.....
reg_cmd.ExecuteNonQuery()
In a parameterized query, you don't attach the user input to your sql command. Instead you put placeholders where the value should be placed (#id), then, before executing the query, you add, one by one, the parameters with the same name of the placeholder and its corresponding value.
You need to close your reader using checker.Close() as soon as you're done using it.
Quick and dirty solution - issue checker.Close() as a first command of both IF and ELSE block.
But (better) you don't need a full blown data reader to check for record existence. Instead you can do something like this:
chk_cmd = New SqlCommand("SELECT TOP (1) 1 FROM UsersInfo WHERE IDnumber = '" & ID & "'", reg_con)
Dim iExist as Integer = chk_cmd.ExecuteScalar()
If iExist = 1 Then
....
This approach uses ExecuteScalar method that returns a single value and doesn't tie the connection.
Side note: Instead of adding parameters like you do now - directly to the SQL String, a much better (and safer) approach is to use parametrized queries. Using this approach can save you a lot of pain in the future.

Trying to update record, keep getting this error vb.net

I'm sure this question will be easy for you lot... :)
I'm simply trying to update an existing record in my database using the following:
Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
If Not cnn.State = ConnectionState.Open Then
cnn.Open()
End If
cmd2.Connection = cnn
cmd2.CommandText = "UPDATE HireItemRecord SET HireItemBeginDate = " & TextBox45.Text & _
" ,HireItemEndDate = " & TextBox44.Text & _
" ,HireItemCost = " & TextBox16.Text & _
" ,PaymentMethod = " & TextBox17.Text & _
" ,Staff_Id = " & TextBox19.Text & _
" ,HireItemNotes = " & TextBox18.Text & _
" ,HireItemReturnDate = " & TextBox43.Text & _
"WHERE HireRecord_Id = " & TextBox13.Text
cmd2.ExecuteNonQuery()
ds1.Clear()
daHireItemRecord.Fill(ds1, "PersonDetails")
cnn.Close()
End Sub
However no matter what record is selected and whatever details are in the boxes I keep getting this same error over and over:
SqlException was unhandled
Incorrect syntax near '12'.
When there is absolutely nothing in the textboxes the error changes to:
Incorrect syntax near ','.
I'm very new to this and I just can't seem to understand why this is happening.
Thank you very much for your help. :)
So much wrong with this.
You need a space after each comma, not before it.
You should be escaping your values before using them in the query. If I put "0 WHERE 1=1 -- " in any of your text boxes, it'll trash your entire table.
You should ALWAYS name your form controls properly. If I sent you back to this code in a year's time and told you there was a problem with TextBox44, would you know what it means? Same goes for your variables. Sometimes it's ok to have i, x or tbl for a variable name, but in general they should be descriptive.
Example for #2, where I've put "'1/1/1999' WHERE 1=1 --" into TextBox45:
`UPDATE HireItemRecord SET HireItemBeginDate = '1/1/1999' WHERE 1=1 -- , HireItemEndDate...`
Everything after the -- becomes a comment, so you get this:
`UPDATE HireItemRecord SET HireItemBeginDate = '1/1/1999' WHERE 1=1`
Can you imagine what would happen if I executed that query? Nothing good.
You should use parameterized queries, as per the recommendations in this question: Algorithm to avoid SQL injection on MSSQL Server from C# code?
You should never use string concatenation to build SQL. It leaves you open to SQL Injection attacks. Try using the SQLCommand object provided in .Net. This allows you to "parameterize" your query and you don't have to worry about where to put " and '.
It will also allow you add parameters naturally without having to convert them to strings. Something like this:
Dim command As New SqlCommand("SELECT * FROM Table", connection)
command.Parameters.Add("#ID", SqlDbType.Int)
command.Parameters("#ID").Value = customerID
I stole that code from the documentation about SQL Parameters here.