INSERT INTO and UPDATE SQL using visual basic into access database - vb.net

I'm working on my A Level coursework using VB forms as my front end and an Access database as the back end. I've tried loads of different ways but I can't get the program to update or insert data into the database.
I know for a fact the connection is fine because I've had no problem retrieving data from access into the program.
This the code for one of the forms:
(the database connection is in a separate form)
Access.ExecQuery("SELECT * FROM Exam;")
Dim user As String = TxtStudent.Text
Dim board As String = CmbBoard.Text
Dim instrument As String = CmbInstrument.Text
Dim grade As String = CmbGrade.Text
Dim result As String = CmbResult.Text
Access.ExecQuery("INSERT INTO Grade (Username, Instrument, Exam Board, Grade, Result) VALUES ('" & user & "', '" & board & "', '" & instrument & ", " & grade & ", " & result & "');")
If Not String.IsNullOrEmpty(Access.Exception) Then MsgBox(Access.Exception) : Exit Sub
The error message says there is a syntax error on INSERT INTO statement.
Am i just being really stupid?

you are missing closing "'" for instrument '" & instrument & "', " . and also, just confirm the values for fields without single quotes(grade ) are numeric otherwise add single quotes

Your single and double parenthesis are a bit of a mess. This alone is a good reason to use parameters but it also protects you from malicious input by users. The important thing with Access is that you must add the parameters in the same order that the command uses them.
Dim cn As New OleDbConnection("Your Access connection string")
Dim s As String = "INSERT INTO Grade (Username, Instrument, Exam Board, Grade, Result) VALUES (#User, #Instrument, #Board, #Grade, #Result);"
Dim cmd As New OleDbCommand(s, cn)
cmd.Parameters.AddWithValue("#User", TxtStudent.Text)
cmd.Parameters.AddWithValue("#Instrument", CmbInstrument.Text)
cmd.Parameters.AddWithValue("#Board", cmdBoard.Text)
cmd.Parameters.AddWithValue("#Grade", CmdGrade.Text)
cmd.Parameters.AddWithValue("#Result", CmdResult.Text)
cn.Open()
cmd.ExecuteNonQuery()
cn.Close()
Double check the data types of the fields and adjust the code if they are not all strings.

In SQL Queries and statements , '(single quote) is used to pass a value of type string to any given parameter(or anything).You mistake was that you forgot to add ' in all the places.
"INSERT INTO Grade (Username, Instrument, Exam Board, Grade, Result) VALUES ('" & user & "', '" & board & "', '" & instrument & ", "'" & grade & "'", "'" & result & "'")"
This will solve it :)
However, one advice, don't give direct values in the statement itself,you are welcoming SQL-Injection.Rather,create parameters and values to them later :
Dim cmd as New SqlCommand("INSERT INTO Grade (Username)Values(#uname)",con)
cmd.Parameter.Add("#uname",SqlDbType.Vachar) = "abc"
Hope this helps to enrich your knowledge :)

You must try this!
Dim con As New OleDbConnection("Your Access connection string here")
Dim s As String = "INSERT INTO Grade ([Username], [Instrument], [Exam Board], [Grade], [Result]) VALUES (#User, #Instrument, #Board, #Grade, #Result)"
Dim cmd As New OleDbCommand(s, con)
con.Open()
cmd.Parameters.AddWithValue("#User", TxtStudent.Text)
cmd.Parameters.AddWithValue("#Instrument", CmbInstrument.Text)
cmd.Parameters.AddWithValue("#Board", cmdBoard.Text)
cmd.Parameters.AddWithValue("#Grade", CmdGrade.Text)
cmd.Parameters.AddWithValue("#Result", CmdResult.Text)
cmd.ExecuteNonQuery()
con.Close()
I hope it will works! :)

Dim con As New OleDbConnection("Your Access connection string here")
Dim s As String = "INSERT INTO Grade ([Username], [Instrument], [Exam Board], [Grade], [Result]) VALUES (#User, #Instrument, #Board, #Grade, #Result)"
Dim cmd As New OleDbCommand(s, con)
con.Open()
cmd.Parameters.AddWithValue("#User", TxtStudent.Text)
cmd.Parameters.AddWithValue("#Instrument", CmbInstrument.Text)
cmd.Parameters.AddWithValue("#Board", cmdBoard.Text)
cmd.Parameters.AddWithValue("#Grade", CmdGrade.Text)
cmd.Parameters.AddWithValue("#Result", CmdResult.Text)
cmd.ExecuteNonQuery()
con.Close()

Related

Building an odbc command string in Visual Basic

I'm trying to figure out where I am going wrong with the following SQL string in VB.NET
Dim SQL As String = "INSERT INTO USERS (" & String.Join(",", PropertyNames) & ", auditmonth) VALUES ('" & String.Join("','", Values) & "',", MonthName & "'"))
I'm getting the following three errors:
End of statement expected
Variable 'MonthName' hides a variable in an enclosing block
Unused local variable 'MonthName'
If I change back to
Dim SQL As String = "INSERT INTO USERS (" & String.Join(",", PropertyNames) VALUES ('" & String.Join("','", Values) & "')"
Then everything works fine. But what I'm trying to do is just add the current month to the database entry. The variable MonthName gets populated successfully. I'm just screwing something up with the syntax of the SQL command.
You should try breaking it up to multiple lines, and debug it to review the whole string constructed:
"INSERT INTO USERS (" &
String.Join(",", PropertyNames) &
", auditmonth) VALUES ('" &
String.Join("','", Values) & "','" &
MonthName & "')"
If your VB.NET compiler supports it, use this string substitution syntax for better readability:
String.Format(
"INSERT INTO USERS ({0}, auditmonth) VALUES ('{1}','{2}')",
String.Join(",", PropertyNames),
String.Join("','", Values),
MonthName)
and, do as #vku says!
You really should use SQL parameters to pass the values. If you try to concatenate them in a string, it will break if there is an apostrophe in the value, and it's also vulnerable to SQL injection attacks.
As shown in tinamzu's answer, it is better to spread the code out over several lines to make it easier to read. Also, use as many variables as you like to keep each line simple.
So, you might have something like this:
Dim columnNames = String.Join(",", propertyNames)
Dim valuePlaceholders = String.Join(", ", Enumerable.Repeat("?", values.Count))
Dim sql = String.Format("INSERT INTO USERS ({0}, auditmonth) VALUES ({1}, ?)",
columnNames,
valuePlaceholders)
Using conn As New OleDbConnection("yourConnectionString"),
cmd As New OleDbCommand(sql, conn)
For Each v In values
cmd.Parameters.Add("?", OleDbType.VarChar).Value = v
Next
cmd.Parameters.Add("?", OleDbType.VarChar).Value = monthName
conn.Open()
cmd.ExecuteNonQuery()
End Using
(Change the OleDbType.VarChar to match the relevant database column types.)
If you are using version 2015 or later of Visual Studio, you could use:
Dim sql = $"INSERT INTO USERS ({columnNames}, auditmonth) VALUES ({valuePlaceholders}, ?)"
instead as it is clear using just one line.

Inserting byte() along side strings to SQL database

So here is the predefined SQL statement that is stored in the DAO file. The values are coming from a class. The picture value is an image converted to a byte(). This class is written in VB.net. I'm in a new job and in my previous i used angular and the entity framework so writing SQL statements is new to me. I'm trying to follow existing examples from co workers but they have never inserted images into the database before so i'm kinda on my own. Yes i know i could just store the files in the server and save the paths to them in the database but for whatever reason my network team wants it stored in the database as blobs. So, here is the SQL statement.
"INSERT INTO AuthAccessID" &
"(" &
"FName," &
"MName," &
"LName," &
"Suffix," &
"Address," &
"AddressExt," &
"City," &
"State," &
"Zip," &
"LawFirm," &
"Picture," &
"AddedDate," &
"AddedBy," &
")" &
"VALUES(" &
"" & ReplaceApostrophes(pp.FName) & ", " &
"'" & ReplaceApostrophes(pp.MName) & "', " &
"'" & ReplaceApostrophes(pp.LName) & "', " &
"'" & ReplaceApostrophes(pp.Suffix) & "', " &
"'" & ReplaceApostrophes(pp.Address) & "', " &
"'" & ReplaceApostrophes(pp.AddressExt) & "', " &
"'" & ReplaceApostrophes(pp.City) & "', " &
"'" & ReplaceApostrophes(pp.State) & "', " &
"'" & ReplaceApostrophes(pp.Zip) & "', " &
"'" & ReplaceApostrophes(pp.LawFirm) & "', " &
"'" & pp.Picture & "', " &
"'" & pp.AddedDate & "', " &
"'" & ReplaceApostrophes(pp.AddedBy) & "')
the pp.Picture is the Byte(). The error i'm getting is:
Operator '&' is not defined for types 'String' and 'Byte()'
i have googled around but cannot find anything. Does anyone have any idea how to correct this? or is there a better way to write the SQL statement? If i can't get this to work the network team said i can use the server file method but they are really pushing the blob in SQL storage instead. Thanks in advance.
Always use Parameters to avoid sql injection, make you sql statement easier to write and read, and make sure you are sending the correct datatypes. Parameters will also allow apostrophes. Use the .Add method. 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
Here is another
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
In the code below, I had to guess at the SqlDbType and Size. Check your database for the correct information.
Connections and commands are using unmanaged resources. They release these resources in their .Dispose method so this method must be called. Using...End Using blocks take care of closing and disposing objects even if there is an error.
I assumed pp was an instance of a class. I gave the class the name Person. Correct this to the real class name.
Private ConStr As String = "Your connection string"
Private Sub InsertAuthAccessID(pp As Person)
Dim sql = "INSERT INTO AuthAccessID (
FName,
MName,
LName,
Suffix,
Address,
AddressExt,
City,
State,
Zip,
LawFirm,
Picture,
AddedDate,
AddedBy)
VALUES (
#FName,
#MName,
#LName,
#Suffix,
#Address,
#AddressExt,
#City,
#State,
#Zip,
#LawFirm,
#Picture,
#AddedDate,
#AddedBy)"
Using cn As New SqlConnection(ConStr),
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("#FName", SqlDbType.VarChar, 50).Value = pp.FName
cmd.Parameters.Add("#MName", SqlDbType.VarChar, 50).Value = pp.MName
cmd.Parameters.Add("#LName", SqlDbType.VarChar, 100).Value = pp.LName
cmd.Parameters.Add("#Suffix", SqlDbType.VarChar, 20).Value = pp.Suffix
cmd.Parameters.Add("#Address", SqlDbType.VarChar, 200).Value = pp.Address
cmd.Parameters.Add("#AddressExt", SqlDbType.VarChar, 50).Value = pp.AddressExt
cmd.Parameters.Add("#City", SqlDbType.VarChar, 100).Value = pp.City
cmd.Parameters.Add("#State", SqlDbType.VarChar, 50).Value = pp.State
cmd.Parameters.Add("#Zip", SqlDbType.VarChar, 20).Value = pp.Zip
cmd.Parameters.Add("#LawFirm", SqlDbType.VarChar, 200).Value = pp.LawFirm
cmd.Parameters.Add("#Picture", SqlDbType.VarBinary).Value = pp.Picture
cmd.Parameters.Add("#AddedDate", SqlDbType.Date).Value = pp.AddedDate
cmd.Parameters.Add("#AddedBy", SqlDbType.VarChar, 50).Value = pp.AddedBy
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
EDIT:
In older versions of VB that did not support multiline String literals, you can use an XML literal instead:
Dim sql = <sql>
INSERT INTO AuthAccessID (
FName,
MName,
LName,
Suffix,
Address,
AddressExt,
City,
State,
Zip,
LawFirm,
Picture,
AddedDate,
AddedBy)
VALUES (
#FName,
#MName,
#LName,
#Suffix,
#Address,
#AddressExt,
#City,
#State,
#Zip,
#LawFirm,
#Picture,
#AddedDate,
#AddedBy)
</sql>
Using cn As New SqlConnection(ConStr),
cmd As New SqlCommand(sql.Value, cn)
Too long and involved for a comment. You have the following snippet in your code:
")" &
"VALUES(" &
"" & ReplaceApostrophes(pp.FName) & ", " &
"'" & ReplaceApostrophes(pp.MName) & "', " &
That is an error. FName is a string and must be treated in exactly the same manner as you do with MName. It is missing the single quote delimiters.
More generally, this approach relies on converting all your "fields" into literals to embed them as strings within your tsql statement. So the question now becomes how do you "write" a binary literal in tsql. You would do that by generating a string like this: 0x69048AEFDD010E. Documentation for tsql constants is here. Knowing that, the next issue is how to do that in your dev language - which is not something I can answer. This look promising.
But before you go down this path, use parameterization and you NEVER have to deal with this ever again.
I come from a MSAccess background, so I code quite much the same way I did in VBA or now with VB.net
Here the code I would use:
Dim sFields() As String
sFields = Split("FName,MName,LName,Suffix,Address,AddressExt,City,State,Zip,LawFirm,AddedDate,AddedBy", ",")
Dim rst As DataTable
Dim da As SqlDataAdapter
rst = MyrstEdit("select * from AuthAccessID where id = 0", da, strcon)
With rst.Rows.Add
For Each s In sFields
.Item(s) = GetValue(pp, s)
Next
End With
da.Update(rst)
And I have two helper routines. The first one gets any class property by a "string" value.
Since by luck, you have field names and the class members are the same!
Public Function GetValue(ByRef parent As Object, ByVal fieldName As String) As Object
Dim field As FieldInfo = parent.[GetType]().GetField(fieldName, BindingFlags.[Public] Or BindingFlags.Instance)
Return field.GetValue(parent)
End Function
And then I have a datable routine - that gets me the data table, and is this:
Public Function MyrstEdit(strSQL As String, ByRef oReader As SqlDataAdapter) As DataTable
Dim mycon As New SqlConnection(strCon)
oReader = New SqlDataAdapter(strSQL, mycon)
Dim rstData As New DataTable
Dim cmdBuilder = New SqlCommandBuilder(oReader)
Try
oReader.Fill(rstData)
oReader.AcceptChangesDuringUpdate = True
Catch
End Try
Return rstData
End Function
So, to get all the data types and structure? I pass a dummy sql that returns no rows. (no rows are returned, but we DO GET the valuable table data types when we do this dummy table pull!). In most cases, if the PK is a autonumber, then I use id = 0.
that same MyRstEdit() code bit has tons of uses! You can now deal with a table in a nice structure, loop it, shove it into a combo box, or datagrid. And as it shows, also allows editing of the data - all with type checking.
The REAL trick and tip I am sharing here? Break out your common data routines to about 2-3 routines like MyRstEdit().
That way, you really don't have to deal with messy in-line sql, or every time you need to work on a table, you don't wire truckloads of code. And the real beauty here is that data typing is done for you - you don't have line after line of parameters, nor line after line of data typing for each column.
So, I hope this post gives you some ideas. But it also nice since I get to code much like I did in MSAccess, and that includes writing VERY little code for updates such as this.
The ideas here are just that - a different approach. The other approaches here are also just fine. (but are quite a bit more code then I perfer).
There are times when using a data table is a rather nice - and I think this is such an example.
And while I am oh so often used to referencing columns as a table collection? The cool trick here is I am also referencing each member of the class with a string too!

Issues trying to add records to an access database through vb.net

I am trying to add a record to a table in a Microsoft Access database through Visual Basic.
This is the code I'm using at the moment: (Within a sub)
Dim OleDbConstring As String = My.Settings.CMDataBaseConnectionString & ";"
Dim Con As OleDbConnection = New OleDbConnection(OleDbConstring)
Dim Cmd As New OleDbCommand
MsgBox("Adding?")
Cmd.Connection = Con
Cmd.CommandText = "INSERT INTO Users (Username, [Password], IsAdmin, TeacherID) VALUES ('" &
NewUsername.Text & "', '" &
NewPassword.Text & "', " &
NewIsAdmin.Checked().ToString & ", " &
NewTeacher.SelectedValue & ")"
Con.Open()
Cmd.ExecuteNonQuery()
Con.Close()
There are no errors thrown and the program doesn't stop at all, I can see the message box so I know the code is being run. However there are no changes made to the database each time. I have checked the field data types and everything is as it should be.
The scenario is a user selects a user, a username (turned into TeacherID), a password, and ticks if they're an admin or not. When they click a button, that code is run.
Also; I am aware that I should be using parameters to avoid SQL string injection, I am only writing it like this to be sure incorrect parameter coding (etc.) isn't contributing to the problem

data is not inserted to database

i tried to insert the data into database with this code
Public Sub AddUser()
Dim con As dbConn = New dbConn()
Dim SqlSelect As String
SqlSelect = "SELECT * FROM login Where user_id='" & WorkerID_.Text & "'"
Dim cmd As New OleDbCommand(SqlSelect, con.oleconnection)
Dim reader As OleDbDataReader
Dim da As New OleDbDataAdapter
con.open()
reader = cmd.ExecuteReader()
reader.Read()
If reader.HasRows() Then
reader.Close()
con.close()
FailureText.Text = "User ID already exists!"
Else
reader.Close()
con.close()
Dim InsertSQL As String
InsertSQL = "INSERT INTO login (user_id, user_role, user_password, user_status) VALUES "
InsertSQL &= "('" & WorkerID_.Text & "', "
InsertSQL &= "'Worker', "
InsertSQL &= "'12345', 1)"
Dim SqlUpdate As String
SqlUpdate = "INSERT INTO Worker (ID, WorkerID, WorkerName, DoB, Address, Phone, Email, CompanyName, PassportNum, PassportExp, VisaExp, VisaStatus, user_id) VALUES (default,"
SqlUpdate &= "'" & WorkerID_.Text & "', "
SqlUpdate &= "'" & WorkerName.Text & "', "
SqlUpdate &= "'" & DoB.Text & "', "
SqlUpdate &= "'" & Address.Text & "', "
SqlUpdate &= "'" & Phone.Text & "', "
SqlUpdate &= "'" & Email.Text & "', "
SqlUpdate &= "'" & Company.SelectedValue & "', "
SqlUpdate &= "'" & PassNum.Text & "', "
SqlUpdate &= "'" & PassExp.Text & "', "
SqlUpdate &= "'" & VisaExp.Text & "', "
SqlUpdate &= "'No Visa', "
SqlUpdate &= "'" & WorkerID_.Text & "') "
Dim insertCommand As New OleDbCommand(SqlUpdate, con.oleconnection)
Dim cmd1 As New OleDbCommand(InsertSQL, con.oleconnection)
Try
con.open()
cmd1.ExecuteNonQuery()
insertCommand.ExecuteNonQuery()
Catch
FailureText.Text = "Unable to add user"
Finally
con.close()
End Try
End If
Response.Redirect("Workers.aspx")
End Sub
the Insert into login part is working. the data is well inserted. but for the insert into worker part is not working. the data is not inserted into the table. the program shows no error and it still can work. what could possibly wrong with this?
Read another answer on OleDb I just answered on another post. You will be wide open to sql-injection too. Parmaeterize queries. By you concatenating strings to build one command, what if one value has a single-quote within the text entry. You are now hosed. What if someone puts malicious SQL commands and then deletes your records or entire table(s). Learn to parameterize your queries and also clean values, especially if coming from a web interface.
Your commands should probably be updated something like
Dim con As dbConn = New dbConn()
Dim SqlSelect As String
SqlSelect = "SELECT * FROM login Where user_id= #parmUserID"
Dim cmd As New OleDbCommand(SqlSelect, con.oleconnection)
cmd.Parameters.AddWithValue( "parmUserID", WorkerID_.Text )
Follow-suit with the Insert and update commands... parameterize them but using #variable place-holders in your commands.
Dim InsertSQL As String
InsertSQL = "INSERT INTO login (user_id, user_role, user_password, user_status) "
InsertSQL &= " VALUES ( #parmUser, #parmRole, #parmPwd, #parmStatus )"
Dim cmdInsert As New OleDbCommand(InsertSQL, con.oleconnection)
cmdInsert.Parameters.AddWithValue( "parmUser", WorkerID_.Text )
cmdInsert.Parameters.AddWithValue( "parmRole", "Worker" )
cmdInsert.Parameters.AddWithValue( "parmPwd", "12345" )
cmdInsert.Parameters.AddWithValue( "parmStatus", 1 )
Dim SqlUpdate As String
SqlUpdate = "INSERT INTO Worker (ID, WorkerID, WorkerName, DoB, Address, Phone, Email, CompanyName, PassportNum, PassportExp, VisaExp, VisaStatus, user_id) "
SqlUpdate &= " VALUES ( #parmID, #parmName, #parmDoB, etc... ) "
Dim cmdUpdate As New OleDbCommand(SqlUpdate, con.oleconnection)
cmdUpdate.Parameters.AddWithValue( "parmID", WorkerID_.Text )
cmdUpdate.Parameters.AddWithValue( "parmName", WorkerName.Text )
cmdUpdate.Parameters.AddWithValue( "parmDoB", DoB.Text )
-- etc with the rest of the parameters.
Final note. Make sure the data types you are trying to insert or update are of same type expected in the table. Such example is your "Birth Date" (DoB) field. If you are trying to insert as simple text, and it is not in an auto-converted format, the SQL-Insert might choke on it and fail. If you have a textbox bound to a DateTime type, then your parameter might be Dob.SelectedDate (such as a calendar control), or you could pre-convert from text to a datetime and then use THAT as your parameter value.
Other numeric values, leave as they are too, they should directly apply for the insert. You could also identify the AddWithValue() call the data type the parameter should represent (string, int, double, datetime, whatever)
You seem to have 12 parameters you wish to insert, and 13 arguments in the VALUES part of your insert query. is the Default seen in the values section below intentional?
INSERT INTO Worker (ID, ... VisaStatus) VALUES (default,"
ensure you have the correct number of parameters defined and added, then let us know, but i could be missing something else.

Getting error while running the query [duplicate]

This question already has an answer here:
Why error ???? Syntax error in INSERT INTO statement
(1 answer)
Closed 7 years ago.
Here is my code.
Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\speednet\speed_net.accdb")
Dim com As New OleDbCommand
con.Open()
com.Connection = con
com.CommandText = "insert into users (name,username,password,user_type) values ('" & name1.Text & "' ,'" & username.Text & "' ,'" & password.Text & "','" & account_type.Text & "')"
com.ExecuteNonQuery()
The error:
Syntax error in insert into statement ...
Cant find out the problem.
Password is a reserved keyword in access. You need square brackets around that word.
But your query should also be modified to use a parameter approach instead of string concatenation, otherwise more dangerous situation will be possible. Read about Sql Injection and what happen if one of your concatenated string contains a single quote.
So
Using con = New OleDbConnection("....")
Using com = New OleDbCommand("insert into users " & _
"(name,username,[password],user_type) " & _
"values (#name, #uname,#pass,#acctype)", con)
con.Open()
com.Parameters.AddWithValue("#name", name1.Text)
com.Parameters.AddWithValue("#uname", username.Text)
com.Parameters.AddWithValue("#pass", password.Text)
com.Parameters.AddWithValue("#acctype", account_type.Text)
com.ExecuteNonQuery()
End Using
End Using