Can you please help me, what the problem of my code:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
'UPDATE Data
openCon()
Try
cmd.Connection = con
cmd.CommandText = "UPDATE emp_table SET FNAME = '" & TextBox1.Text & "', LNAME= '" & TextBox2.Text & "', AGE = '" & TextBox3.Text & "', GENDER ='" & Gender & "', OFFICE STAFF= '" & ComboBox1.Text & "' Where ID ='" & TxtID.Text & "' "
cmd.ExecuteNonQuery()
con.Close()
MsgBox("Suceessfully Updated Record")
TxtID.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
RBMale.Checked = False
RBFemale.Checked = False
ComboBox1.Text = ""
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
There are many problems in your code and if you look around this site I think you will find many partial answers that step by step will help you solve your problems. So I try to give you an answer where all the problems are examined, discussed and solved.
First problem: How do you handle the connection.
It seems that you have a global connection instance called con that you open with openCon. This is not a good approach and always a source of problems. You always need to check if the connection is closed properly or not. For example, in the code above you have forgot to close the connection in case of exception and this will lead to other exceptions in some code not related to this one. You keep resources on the server locked to you and this will decrease the performance of every one connection to that server.
I would change your openCon to this
Public Function openCon() as MySqlConnection
Dim con as MySqlConnection = new MySqlConnection(....here connection string ...)
con.Open()
return con
End Function
This will create a new instance of the MySqlConnection every time you call this method Now you can remove the global connection instance and use the one returned by openCon in this way
Using con As MySqlConnection = openCon()
.... code that use the local con object
End Using
This will close and destroy the connection even if an exception occurs inside the Using block and the ADO.NET libraries are smart enough to use a thing called Connection Pooling to reduce the time required to build and open a connection with the same connection string.
Second problem: The syntax error.
Looking at the point of the error suggested by the message I can see a field name composed by two words separated by a space. This is fine, but then you should remember that the sql parser cannot understand this and you need to help it enclosing the two words in a backtick character (ALT+096) so the parser understand that this is a single field name. Given the fact column names are an internal information of no concern for your end user then why use spaces in column names? If possible remove the space in column names.
Third problem: Sql Injection and other syntax errors
You are concatenating strings to build an sql command. But this is an easy target for wannabe hackers. Suppose that I write in your textBox1 this string instead of a First Name: Mario'; --
Then your command becomes
UPDATE emp_table SET FNAME = 'Mario'; -- xxxxxxxxxxxx
everything after -- is considered a comment and the query is still executable, but it changes every record in emp_table to have a first name equal to Mario.
But the query could fail as well if someone writes a Last Name that contains an apostrophe like O'Leary just now the query is no more syntactically valid.
The solution to this is always one. Use Parameters.
Recap of changes to your code.
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim cmdText as String = "UPDATE emp_table SET FNAME = #fname,
LNAME= #lname, AGE = #age, GENDER =#gender,
`OFFICE STAFF` = #staff
Where ID =#id"
Using con as MySqlConnection = openCon()
Using cmd as MySqlCommand = new MySqlCommand(cmdText, con)
Try
cmd.Parameters.Add("#fname", MySqlDbType.VarChar).Value = textBox1.Text
cmd.Parameters.Add("#lname", MySqlDbType.VarChar).Value = textBox2.Text
cmd.Parameters.Add("#age", MySqlDbType.VarChar).Value = textBox3.Text
cmd.Parameters.Add("#gender", MySqlDbType.VarChar).Value = gender
cmd.Parameters.Add("#staff", MySqlDbType.VarChar).Value = combobox1.Text
cmd.Parameters.Add("#id", MySqlDbType.VarChar).Value = txtID.Text
cmd.ExecuteNonQuery()
MsgBox("Suceessfully Updated Record")
TxtID.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
RBMale.Checked = False
RBFemale.Checked = False
ComboBox1.Text = ""
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Using
End Using
End Sub
In the recap I have added parameters for every single field that you want to update. But remember. Parameters should have a Type (The MySqlDbType here) that should match the type of the field and the value should be of the same type. For example it seems improbable that Age is a varchar field. So you should convert TextBox3.Text to an integer if the field is an integer.
Related
I get these two error messages,
'ExecuteReader' is not a member of 'WindowsApplication1.MySqlCommand'
Too many arguments to 'Public Sub New()' {This error occurs in (query, conn) field}
Little explanation about what I am trying to do
Here I am trying to make an application that will input data to separate databases (Men, Women and Kids) using If pub = "" (pub is mentioned in another) Then according to ComboBox1 the table may get differ. According to the table the values need to be inserted.
This is the code I am using
Dim T As String
T = ComboBox1.Text
If pub = "Women" Then
conn = New MySqlConnection
conn.ConnectionString = "server=localhost;user=root;password=1234;database=women_clothing"
Dim reader As MySqlDataReader
Try
conn.Open()
Dim query As String
query = "INSERT INTO [" + T + "] VALUES ('" & TextBox1.Text & "','" & TextBox2.Text & "','" & TextBox3.Text & "','" & TextBox4.Text & "'," & Val(TextBox5.Text) & "," & Val(TextBox6.Text) & ");"
command = New MySqlCommand(query, conn)
reader = Command.ExecuteReader
MessageBox.Show("Data Saved")
conn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
conn.Dispose()
End Try
loadtable()
ElseIf pub = "Men" Then
Else
End If
loadtable()
Thank You
You shouldn't use ExecuteReader for executing a statement that inserts data. ExecuteReader is for SELECT queries. ExecuteNonQuery is for INSERTs
Your code should look like:
Using conn = New MySqlConnection("server=localhost;user=root;password=1234;database=women_clothing")
Using cmd = New MySqlCommand("INSERT INTO tableName VALUES (#p1,#p2,#p3,#p4,#p5,#p6)", conn)
conn.Open()
cmd.Parameters.AddWithValue("#p1", TextBox1.Text)
cmd.Parameters.AddWithValue("#p2", TextBox2.Text)
cmd.Parameters.AddWithValue("#p3", TextBox3.Text)
cmd.Parameters.AddWithValue("#p4", TextBox4.Text)
cmd.Parameters.AddWithValue("#p5", TextBox5.Text)
cmd.Parameters.AddWithValue("#p6", TextBox6.Text)
cmd.ExecuteNonQuery()
End Using
End Using
I've also demonstrated how to use parameters; always use parameters. Your code as it stands is massively at risk of SQL injection attack hacking, and if that doesn't dissuade you enough to not write code in this way, bear in mind that your app will crash if anyone enters an apostrophe in one of your textboxes (which will then give the more astute tech whizzkids using it the idea that it's prone to injection hacking, then they will break into it) which looks bad to the end user (and makes them complain to your helpdesk/you).
It doesn't matter that "it's only a simple app for my grandma to index her vinyl collection" - this is about NOT learning a pattern of behavior that is plain risky, bordering on career-limiting if you want to take your coding skills into the software development world. As the VTech hack linked above shows, there are now 5 million images of children floating around out there whose parents never authorized their release, all because a few people didn't take proper precautions in doing their job. If any of my developers wrote an injection prone SQL, given the nature of one of the industries I work in, they'd just get fired.
Also, please get into the habit of renaming your textboxes after you add them to the form. It's incredibly difficult for anyone (yourself included, 6 months down the line) to have to constantly look up "hmm, what is the first name textbox? is it textbox2 or textbox3?" it takes about 2 seconds to type something new in the (Name) line of the property grid after you add the textbox to the form; firstNameTextBox is far better than textBox2
With credit to #Caius, this is a variation using ConnectionStringBuilder, a With block, a composite Using block and string interpolation, just for illustration.
NOTE the use of As in lieu of = when declaring the connection and command; this is to formally set the types rather than rely on Infer to determine them.
Dim connStr As New MySqlConnectionStringBuilder() With {
.Server = "localhost",
.Database = "women_clothing",
.UserID = "root",
.Password = "1234"
}
' -> "server=localhost;database=women_clothing;user id=root;password=1234"
Using conn As New MySqlConnection(connStr.ConnectionString),
cmd As New MySqlCommand($"INSERT INTO [{T}] VALUES (#p1, #p2, #p3, #p4, #p5, #p6)", conn)
conn.Open()
With cmd
.Parameters.AddWithValue("#p1", TextBox1.Text)
.Parameters.AddWithValue("#p2", TextBox2.Text)
.Parameters.AddWithValue("#p3", TextBox3.Text)
.Parameters.AddWithValue("#p4", TextBox4.Text)
.Parameters.AddWithValue("#p5", TextBox5.Text)
.Parameters.AddWithValue("#p6", TextBox6.Text)
.ExecuteNonQuery()
End With
conn.Close()
End Using
I'm trying to create a register for using mysql table as if username and pass is already added it output a msgbox saying you are already registered but what happen is that it always add it even if it already exists ..
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim cn As New SqlConnection
Dim cmd As New SqlCommand
Dim cmd2 As New SqlCommand
Dim dr As SqlDataReader
cn.ConnectionString = "Server=localhost;Database=test;Uid=sa;Pwd=fadyjoseph21"
cmd.Connection = cn
cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES('" & TextBox1.Text & "','" & TextBox2.Text & "')"
cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'"
cn.Open()
MsgBox("Registered")
cmd.ExecuteNonQuery()
dr = cmd.ExecuteReader
If dr.HasRows Then
MsgBox("You're already registered")
End If
End Sub
End Class
You never actually check to see if the username exists.
You define a query here:
cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'"
But never execute that query. Instead, you just execute the INSERT query:
dr = cmd.ExecuteReader
So the INSERT is always performed. And since an INSERT doesn't return rows, you don't see the message box.
First thing's first, fix your SQL injection vulnerability. (Personal policy, I don't like writing SQL-injectable code in an answer.) Use query parameters instead of directly concatenating user input as code:
cmd2.CommandText = "SELECT * FROM test2 WHERE username = #Username"
cmd2.Parameters.Add("#Username", SqlDbType.VarChar, 50).Value = TextBox1.Text
dr = cmd2.ExecuteReader
If dr.HasRows Then
MsgBox("You're already registered")
Return
End If
Note a couple of things here:
The use of a query parameter. I had to guess on the type and size of the column in the database, adjust that as necessary.
Only executing this one query. Don't try to execute both queries at the same time, perform the first one and then perform the second one.
You don't need, or even want, to include the password in this query. You're checking if the username already exists, that's all.
Return after showing the message, so the rest of the function doesn't execute.
Then, after that is done, you can perform the INSERT operation:
cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES(#Username,#Password)"
cmd.Parameters.Add("#Username", SqlDbType.VarChar, 50).Value = TextBox1.Text
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 50).Value = TextBox2.Text
cmd.ExecuteNonQuery()
This will perform the INSERT operation. So if the Return above was never encountered then the username is unique and can be inserted.
Also: You should not be storing user passwords in plain text. This is grossly irresponsible to your users and exposes their private data to attackers. Instead, obscure the password with a one-way hash so that it can't be read in its original form.
A couple other things:
Use meaningful variable names. The whole reason you were having this problem was because you were getting confused between cmd and cmd2. If your variable names carry semantic meaning, your code is a lot easier to read and understand.
Make use of the Using block when you have disposable resources, such as a database connection. In general you want to open, use, and close a database connection in as small a scope as possible. Leaving open connections hanging around is a Bad Thing.
Add unique key constraint on username and hence when it already exist it will throw duplicate entry exception.
Secondly, never save plain text password in Database, it must be hasheh and encrypted. I would suggest to better use Bcrypt of atleast level 10 to generate hashed password and also use Bcrypt dynamic salt which is mostly preferred now.
Thirdly, always use parameterized query to avoid your program from mysql injection.
For example:-
Normal:
SELECT * FROM customers WHERE username = 'timmy'
Injection:
SELECT * FROM customers WHERE username = '' OR 1''
is there any possible way to execute this without getting this error "There is already an open DataReader associated with this Connection which must be closed first." i already tried using "dr.close()" and i get another error that says "Invalid attempt to Read when reader is closed." can you help me out?
Heres my code:
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Label2.Text = AllPicker1.Text
Label3.Text = AllPicker2.Text
If AllPicker1.Value >= AllPicker2.Value Then
MsgBox("End Date Must be Greater!")
Else
Dim SQLstatement As String = "SELECT * FROM tblStudInfo,tbl_studentLog WHERE tblStudInfo.StudID = tbl_studentLog.StudentNumber AND tbl_studentLog.LoginDate BETWEEN '" & AllPicker1.Text & "' AND '" & AllPicker2.Text & "'"
OpenData(SQLstatement)
End If
End Sub
Public Sub OpenData(ByRef SQLstatement As String)
Dim cmd As MySqlCommand = New MySqlCommand
With cmd
.CommandText = SQLstatement
.CommandType = CommandType.Text
.Connection = SqlConnection
dr = .ExecuteReader()
End With
While dr.Read
Dim SQLstatementSave As String = "INSERT INTO tbl_report (RepStudNo,RepName,RepCourse,RepDept,RepLogTime,RepLogdate) VALUES ('" & dr("StudID") & "','" & dr("Name") & "','" & dr("Course") & "','" & dr("Dept") & "','" & dr("LoginTime") & "','" & dr("LoginDate") & "') "
dr.Close()
Save(SQLstatementSave)
End While
SqlConnection.Close()
SqlConnection.Dispose()
SqlConnection.Open()
End Sub
Public Sub Save(ByRef SQLstatementSave As String)
Dim cmd As MySqlCommand = New MySqlCommand
With cmd
.CommandText = SQLstatementSave
.CommandType = CommandType.Text
.Connection = SqlConnection
.ExecuteNonQuery()
End With
SqlConnection.Close()
SqlConnection.Dispose()
SqlConnection.Open()
End Sub
End Class
It seems you are using only one SqlConnection. For most database systems you cannot reuse the connection while you are reading from it. You can either read all data into memory / DataTable and work on the rows after that or use a different SqlConnection for your Inserts.
When working with SqlConnections, Readers and Commands I find the Using Statement very helpful to visualize object usage and creation.
We can reduce this down to a single query:
INSERT INTO tbl_report
(RepStudNo,RepName,RepCourse,RepDept,RepLogTime,RepLogdate)
SELECT StudID, Name, Course, Dept, LoginTime, LoginDate
FROM tblStudInfo
INNER JOIN tbl_studentLog ON tblStudInfo.StudID = tbl_studentLog.StudentNumber
WHERE tbl_studentLog.LoginDate BETWEEN #StartDate AND #EndDate
Note the use of the full INNER JOIN syntax. The older TableA,TableB syntax for joins should be avoided. Also note the use of placeholders for your dates. This is important.
Now I need to draw attention to a couple functions I saw: OpenData(), and Save().
Those two functions are fundamentally broken, because they force you to build your queries in a way that leaves you vulnerable to sql injection hacking. Someday soon, someone will put a value like this into a textbox that is included with a query:
';DROP Table tbl_studentLog;--
Think carefully about what would happen now if someone entered that into your AllPicker1.Text. It would be hard to do that to a date picker, but I'll bet you have other plain text fields that would allow this. The first character (single quote) in my proposed input would close the string literal in the query. The second character (semi-colon) would end the individual statement, but sql server won't stop executing code. The next set of characters make up an additional statement that would drop your table. The final two characters comment out anything that follows, to avoid sql server rejecting or not committing the command because of syntax errors. Yes, Sql Server will run that additional statement, if that is what you put in a textbox.
So, your methods as written are broken, because the only accept completed sql strings as input. Any function that calls into the database MUST also include a mechanism for accepting query parameters. You ultimately want to be running code more like this:
Public Sub CreateReport(ByVal StartDate As DateTime, ByVal EndDate As DateTime)
Dim sql As String = _
"INSERT INTO tbl_report " & _
" (RepStudNo,RepName,RepCourse,RepDept,RepLogTime,RepLogdate) " & _
" SELECT StudID, Name, Course, Dept, LoginTime, LoginDate " & _
" FROM tblStudInfo " & _
" INNER JOIN tbl_studentLog ON tblStudInfo.StudID = tbl_studentLog.StudentNumber " & _
" WHERE tbl_studentLog.LoginDate BETWEEN #StartDate AND #EndDate"
'.Net is designed such in most cases that you really do want a new SqlConnection for each query
'I know it's counter-intuitive, but it is the right way to do this
Using cn As New SqlConnection("Connection string"), _
cmd As New SqlCommand(sql, cn)
'Putting your data into the query using parameters like this is safe from injection attacks
cmd.Parameters.Add("#StartDate", SqlDbType.DateTime).Value = StartDate
cmd.Parameters.Add("#EndDate", SqlDbType.DateTime).Value = EndDate
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
One thing to point out here is that at first glance I don't close the connection. However, the Using block will ensure that the connection is closed promptly... even if an exception is thrown. Your existing code will leave the connection hanging in the case of a exception.
Also note that this neatly side-steps the whole issue of needing to execute a separate query while your reader is opened... but if you ever do really need to do this (it's rare), the answer is simple: use a separate connection.
Instead of:
Dim SQLstatementSave As String = "INSERT INTO tbl_report
(RepStudNo,RepName,RepCourse,RepDept,RepLogTime,RepLogdate)
VALUES ('" & dr("StudID") & "','" & etc.
Try using .ToString on your DR() references.
Dim SQLstatementSave As String = "INSERT INTO tbl_report
(RepStudNo,RepName,RepCourse,RepDept,RepLogTime,RepLogdate)
VALUES ('" & dr("StudID").ToString & "','" & etc.
Why won't this delete the data in my MySQL database!?
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim dbCon As MySqlConnection
Dim strQuery As String = ""
Dim SQLCmd As MySqlCommand
Dim DR As MySqlDataReader
Try
dbCon = New MySqlConnection("Server=Localhost;Database=myusers;Uid=root;Pwd=Mypassword")
strQuery = "DELETE settings FROM settings WHERE user=" & Me.loginuser.Text
'* FROM settings WHERE user = "Testuser"'
SQLCmd = New MySqlCommand(strQuery, dbCon)
' OPEN THE DB AND KICKOFF THE QUERY
dbCon.Open()
DR = SQLCmd.ExecuteReader
While DR.Read
req1.Text = "" And exlink.Text = ""
End While
' DONE! Close DB
DR.Close()
dbCon.Close()
Catch ex As Exception
TextBox8.Text = ("Fail" & vbCrLf & vbCrLf & ex.Message)
End Try
Here is a picture of my database:
Alternatively I could somehow make it replace what is already in the database, in which case please help me with that.
Try
strQuery = "DELETE FROM settings " _
& " WHERE user = '" & Me.loginuser.Text & "'"
but as was stated earlier, you should be using parameterized queries. If you had a user named O'Brien then your query (as composed above) would fail because of the embedded single quote. When you use DELETE, you are deleting entire records and you already specify the table name in the FROM clause.
I will try to change your code in this way
Using con = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText = "DELETE * FROM settings WHERE user = #ulogin"
Using cmd = new MySqlCommand(sqlText, con)
cmd.Parameters.AddWithValue("#ulogin", Me.loginuser.Text)
cmd.ExecuteNonQuery()
End Using
End Using
First and foremost, do not use string concatenation to create command texts to pass to the database engine. In that way you risk Sql Injections, also, if the user name contains a single quote (i.e. O'Hara) your code will fail with a syntax error (Same problems arise for date formatting, parsing numeric decimals and other globalization issues). Instead a parametrized query like the one in code above will avoid all of these problems.
In a parametrized query, the text of the query doesn't contains the actual value for the search condition or the update or insert data. Instead it contains placeholders ( in our case it is called #ulogin). The correct value to insert at the placeholders position is specified using one or more MySqlParameter added to the Parameters collection of the MySqlCommand. In this case I have used the AddWithValue method that derives the correct datatype directly from the datatype of the value. Because Me.loginuser.Text is a string value then the parameter will be treated as a string value replacing incorrect single quotes and removing extraneus characters usually used to Mount Sql Injections Attacks. The engine will do the rest inserting the correct value at the placeholder at execution time
EDIT: Seeing your comment about the MySql connector used, I will try to update my answer to show a semi-equivalent version for NET 1.
Try
Dim con As MySqlConnection = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText as String = "DELETE * FROM settings WHERE user = #ulogin"
Dim cmd As MySqlCommand = new MySqlCommand(sqlText, con)
Dim par As MySqlParameter = New MySqlParameter("#ulogin", MySqlDbType.VarChar)
par.Value = Me.loginuser.Text
cmd.Parameters.Add(par)
cmd.ExecuteNonQuery()
Finally
con.Close()
End Try
I am not sure if the connector 1.0.10 supports the parameter name with the # prefix or just the : prefix
i dont think you can use double quotes in mysql, i think its single quotes only. try
Query = "DELETE * FROM settings WHERE user = '" & Me.loginuser.Text & "'"
I have the following controls:
textbox1 - this is where i type a message.
listbox1 - this is where i display the messages.
button1 - this is what posts my messages to the server.
StatusStrip1.Title1 - this is where the current user's title will go. (i.e: Administrator, manager... etc.)
I have a table on a MYSQL database called "messages" and a column called "message". When i type something into textbox1 and click button1 i want to add a row to "messages" under the column "message" with the title and message as its value.(separated by a hyphen, dash, or other small delimiter)Then reload listbox1's contents to show the new message.
so i want the final message to be something like:
Administrator - Hello World!
I currently have the following code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sqlpost As MySqlCommand = New MySqlCommand("INSERT INTO messages(message) VALUES(?name - ?message)"";", con)
sqlpost.Parameters.AddWithValue("?name", Title2.Text)
sqlpost.Parameters.AddWithValue("?message", TextBox1.Text)
Try
con.Close()
con.Open()
' Sending message.
If TextBox1.Text = "" Then
MessageBox.Show("You forgot to type a message!")
Else
sqlpost.ExecuteNonQuery()
' Reloading messages.
ListBox1.Items.Clear()
reader = sqlmessages.ExecuteReader()
While (reader.Read)
ListBox1.Items.Add(reader.Item("message"))
ListBox1.Items.Add("")
End While
reader.Close()
con.Close()
TextBox1.Text = ""
Label4.Text = "Message Sent!"
Timer2.Start()
End If
Catch myerror As MySqlException
MessageBox.Show("Error sending message to server: " & myerror.Message)
End Try
End Sub
I had it working before, but when i made changes to it, it came up with various sql statement syntax errors... (stuff like invalid truncated value of "Administrator", or invalid DOUBLE value "hello") and now it won't even display any messages currently in the "messages" table...)
If anyone could tell me what i'm doing wrong, or a more efficient way of doing this then i would greatly appreciate it! Thanks!
One thing I see that looks incorrect is that you are using "?" for you parameter names in the query. The default character to use for parameter names is to start them with "#". Although I think there's a connection string option to use "?" as that is what was used in the older versions of the MySQL connector, but the current default is "#". Also, there seems to be some problems with your command in general. You have:
Dim sqlpost As MySqlCommand = New MySqlCommand("INSERT INTO messages(message) VALUES(?name - ?message)"";", con)
it should probably be something more like
Dim sqlpost As MySqlCommand = New MySqlCommand("INSERT INTO messages(message) VALUES(#message);", con)
I fixed up the query a bit, and replaced the ? with #. You you can do the concatenation of name and message (as you cleared up in the comment) in VB, with some code such as this:
sqlpost.Parameters.AddWithValue("#message", Title2.Text & " - " & Title2.Text)
I also see that you are calling
sqlmessages.ExecuteReader()
but I don't see where this is being initialized.
You should have to use single parameter.
Dim con as New MySqlConnection
con.ConnectionString="set_connection_string_here"
Dim sqlpost As MySqlCommand = New MySqlCommand("INSERT INTO `messages` (`message`) VALUES (#name)",con)
sqlpost.Parameters.AddWithValue("#name", Title2.Text & " - " & TextBox1.Text)
If TextBox1.Text = "" Then
MessageBox.Show("You forgot to type a message!")
Else
con.Open()
sqlpost.ExecuteNonQuery()
con.Close()
ListBox1.Items.Clear()
sqlmessages.CommandText="select * from `messages`"
sqlmessages.Connection=con
reader = sqlmessages.ExecuteReader()
While (reader.Read)
ListBox1.Items.Add(reader.Item("message"))
End While
reader.Close()
con.Close()
End If