vb.net Writing & Reading Multiline Text in MySQL Database - mysql

I'm trying to create a messaging system e.g. I have a table in a MySQL database called tbluser which holds the data for every user. One record is one user which has the field of 'StatusMessage'. This field can have values which can be written onto multiple lines, but I am having trouble on how to separate the text this field holds into multiple lines using a ListBox.
Private Sub lstMessages_VisibleChanged(sender As Object, e As EventArgs) Handles lstMessages.VisibleChanged
Dim Query As String = "SELECT StatusMessage FROM tbluser WHERE UserID=#userID"
Using Conn As New MySqlConnection(MySQL.ConnectionDetails)
Using Comm As New MySqlCommand()
With Comm
.Connection = Conn
.CommandText = Query
.CommandType = CommandType.Text
.Parameters.AddWithValue("#userID", CInt(cboSelectUser.SelectedItem.ToString))
End With
Try
Conn.Open()
Dim Reader As MySqlDataReader = Comm.ExecuteReader
lstMessages.Items.Clear()
While Reader.Read OrElse (Reader.NextResult And Reader.Read)
lstMessages.Items.Add(Reader.GetString(0))
End While
Catch ex As MySqlException
End Try
End Using
End Using
End Sub
At the moment, all the text appears onto one line.
Also, another question, how would I insert text into the database with multiple lines.

To solve the problem, what I ended up doing was changing the component used into a RichTextBox. Also, I changed every instance of the string "\n" which is a new line in MySQL to Environment.NewLine().
To insert new messages into the field, I had to select all of the text already in the field and then add to that text so I used a combination of a SELECT query and UPDATE query along with Environment.NewLine() so I can write to new lines.

Related

How to read a value from mysql database?

I want to be able to read a value (in this case an Group ID). All the topics and tutorials I've watched/read take the data and put it into a textbox.
I don't want to put it in a textbox in this case; I want to grab the Group ID and then say:
If Group ID = 4 then login
Here is an image of the database.
Basically, but none of the tutorials I watch or the multiple forums. None of them take a a value and say if value = 4 then login or do something else.
If text = "1" Then
MysqlConn = New MySqlConnection
MysqlConn.ConnectionString =
"server='ip of server'.; username=; password=; database="
Dim READER As MySqlDataReader
Dim member_group_id As String
Try
MysqlConn.Open()
Dim Query As String
Query = "SELECT * FROM `core_members` where name='" & TextBox2.Text & "'"
Query = "SELECT * FROM `nexus_licensekeys` where lkey_key='" & TextBox1.Text & "'"
COMMAND = New MySqlCommand(Query, MysqlConn)
READER = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While READER.Read
count = count + 1
End While
Here is what I have so far. I'm kind of new implementing mysql data with visual basic and only recently started to get into it. I'm not sure what comes next or how to even start with reading the group id etc.
As I said any help from here on out would be highly appreciated of how to read the group id and say if this group id = this number then do this or that. I'm sure you get the idea.
I divided the code into UI Sub, and Data Access Function that can return data to the UI. Your Event procedure code should be rather brief and the functions should have a single purpose.
Keep your database objects local to the method. This way you can have better control. The Using...End Using blocks ensure that your database objects are closed and disposed even if there is an error.
I leave it to you to add validation code. Checking for empty TextBox or no return of records.
I hope this serves as a quick introduction to using ADO.net. The take away is:
Use Parameters
Make sure connections are closed. (Using blocks)
Private ConnString As String = "server=ip of server; username=; password=; database="
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim GroupID As String = GetGroupID(TextBox1.Text)
If GroupID = "4" Then
'your code here
End If
Dim LocalTable As DataTable = GetLicenseKeysData(TextBox1.Text)
'Get the count
Dim RowCount As Integer = LocalTable.Rows.Count
'Display the data
DataGridView1.DataSource = LocalTable
End Sub
Private Function GetGroupID(InputName As String) As String
'Are you sure member_group_id is a String? Sure looks like it should be an Integer
Dim member_group_id As String = ""
'You can pass the connection string directly to the constructor of the connection
Using MysqlConn As New MySqlConnection(ConnString)
'If you only need the value of one field Select just the field not *
'ALWAYS use parameters. See comment by #djv concerning drop table
Using cmd As New MySqlCommand("SELECT g_id FROM core_members where name= #Name")
'The parameters are interperted by the server as a value and not executable code
'so even if a malicious user entered "drop table" it would not be executed.
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = InputName
MysqlConn.Open()
'ExecuteScalar returns the first column of the first row of the result set
member_group_id = cmd.ExecuteScalar.ToString
End Using
End Using
Return member_group_id
End Function
Private Function GetLicenseKeysData(InputName As String) As DataTable
Dim dt As New DataTable
Using cn As New MySqlConnection(ConnString)
Using cmd As New MySqlCommand("SELECT * FROM `nexus_licensekeys` where lkey_key= #Name;", cn)
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = InputName
cn.Open()
dt.Load(cmd.ExecuteReader())
End Using
End Using
Return dt
End Function

Transfer the sum of query to label

the query is working on mysql command line but how can i put the sum to the label
Dim SDA As New MySqlDataAdapter
Dim bSource As New BindingSource
Dim dbDataSet As New DataTable
Try
MysqlConn.Open()
Dim Query As String
Query = "select sum(No_Of_Case_To_Be_Deliver) from ordered= '" & totalcase.Text & "'"
COMMAND = New MySqlCommand(Query, MysqlConn)
SDA.SelectCommand = COMMAND
SDA.Fill(dbDataSet)
bSource.DataSource = dbDataSet
MysqlConn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
MysqlConn.Dispose()
End Try
Never concatenate strings to build an Sql statement. Use parameters. You are risking damage to your database.
A DataAdapter will open and close its connection for you as part of the .Fill method. However, if it finds the connection open it leaves it open.
Glad to see you called .Dispose on your connection but you can save yourself the trouble by using `Using...End Using blocks. This will ensure that your database objects are closed and disposed even if there is an error.
Now to the code. You are not Filling or Updating anything so you don't need a DataAdapter for this query. You are not Binding anything so no BindingSource. Bad name for DataTable (dbDataSet) because a DataSet is a different type of object. Anyone trying to maintain your code could be easily confused.
By using parameters you not only save yourself from SQL injection but greatly simplify the Sql statement. No worries about double quotes, single quotes, etc.
Since you are retrieving only a single piece of data, you can use .ExecuteScalar which returns the first column of the first row of the result set.
I separated the code into a Data Access function and User Interface part. This way you can migrate your application to a different platform, say a web app, by just picking up the function as a whole.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lblTotalCases.Text = DirectCast(GetTotalCases(CInt(totalcase.Text)), String)
End Sub
Private Function GetTotalCases(OrderID As Integer) As Integer
Dim TotalCases As Integer
'I made up a query since your query didn't make sense.
Dim Query = "select sum(No_Of_Case_To_Be_Deliver) from OrderDetails Where OrderID = #ID;"
Using MysqlConn As New MySqlConnection("Your Connection String")
Using Command As New MySqlCommand(Query, MysqlConn)
Command.Parameters.Add("#ID", MySqlDbType.Int32).Value = OrderID
MysqlConn.Open()
TotalCases = CInt(Command.ExecuteScalar)
End Using
End Using
Return TotalCases
End Function

How do you restrict what kind of data can be input into a Textbox for Visual Basic?

I have created a simple Windows Forms Application through Visual Studio 2013, with two text boxes and a button, which I linked to a database in MySql through MySql connector. What it does is after I input a product id and status number for a product that is found in table A, clicking the button would transfer certain columns for that product's row from table A to table B, and then the original row in table A after the data is transferred would be deleted. This is done by calling a stored procedure from that MySql database that uses the values inputted in the text boxes as parameters. Here's the code for the app below so far.
**
Imports MySql.Data.MySqlClient
Imports test_mysql_connection
Public Class Form1
Dim cmd As New MySqlCommand
Dim connection As New MySqlConnection("Database=****;" & _
"Data Source=****;" & _
"User Id=****;Password=****")
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
connection.Open()
cmd.Connection = connection
cmd.CommandText = "StoredProcedureC"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#p_product_id", TextBox1.Text)
cmd.Parameters("#p_product_id").Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#p_mission_status", TextBox2.Text)
cmd.Parameters("#p_mission_status").Direction = ParameterDirection.Input
cmd.ExecuteNonQuery()
MessageBox.Show("successfully relocated!")
TextBox1.Clear()
TextBox2.Clear()
connection.Close()
End Sub
End Class
**
As the app currently stands though, even though it successfully performs the task I want it to do, I could literally input anything in those boxes, even if they have nothing to do with anything found in table A, and I would still get the message "successfully relocated!" even if nothing from table A is being transferred to table B. I especially don't want to be able to enter the product id and mission number of something from table A that has already been transferred to B and deleted from A. So I'm wondering about how I can restrict what I can input into these text boxes, and perhaps add a few error messages if a product id and mission status that is inputted isn't found on table A. Thanks for any feedback beforehand!
The simplest way is indicated below. Alternatively you could handle the textbox.Validating event and cancel anything that isn't numeric.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
connection.Open()
if not IsNumeric(TextBox1.Text) then Msgbox("Must be a number") : return
cmd.Connection = connection
cmd.CommandText = "StoredProcedureC"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#p_product_id", TextBox1.Text)
cmd.Parameters("#p_product_id").Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#p_mission_status", TextBox2.Text)
cmd.Parameters("#p_mission_status").Direction = ParameterDirection.Input
dim rows = cmd.ExecuteNonQuery()
if rows <> 0 then
MessageBox.Show("successfully relocated!")
else
MessageBox.Show("no matching rows.")
end if
TextBox1.Clear()
TextBox2.Clear()
connection.Close()
End Sub

How to execute two separate queries from one DBCommand object?

I have the following code that tries to get records from two different tables and then add them to the particular comboboxes. Only the first query works and the second one is ignored.
Try
sqlConn = New MySqlConnection
connStr = New String("Server = localhost; Database = gen_database; Uid = root; Pwd =")
sqlConn.ConnectionString = connStr
myCommand = New MySqlCommand("Select DevCompanyName from developer_name_table; Select DevType from development_type_table")
myCommand.CommandType = CommandType.Text
myCommand.Connection = sqlConn
ComboBox1.Items.Clear()
sqlConn.Open()
MsgBox("Connection Open.")
dR = myCommand.ExecuteReader()
Do While dR.Read()
ComboBox1.Items.Add(dR("DevCompanyName"))
ComboBox2.Items.Add(dR("DevType")) 'Error shows here Could not find specified column in results: DevType
Loop
Catch ex As MySqlException
MsgBox(ex.ToString)
Finally
dR.Close()
sqlConn.Close()
End Try
I can think of another way which is to do it in multiple query but can the code be simplified to something like this?
Using a DBDataReader with 2 queries, only only the first executes because there is no way to signal which table/query each read item is from. Your "double read" loop seems to assume they will be returned at the same time (rather than one query after the other - the same way they are sent to the DBCOmmand); if it did work that way, it would fail whenever there are not the same number of rows in each table.
Using DataTables affords you the chance to simply bind the result to your combos rather than copying data into them:
Dim SQL = "SELECT * FROM Sample; SELECT * FROM Simple"
Dim ds As New DataSet
Using dbcon As New MySqlConnection(MySQLConnStr),
cmd As New MySqlCommand(SQL, dbcon)
dbcon.Open()
Dim da As New MySqlDataAdapter(cmd)
da.Fill(ds)
End Using
' debug results
Console.WriteLine(ds.Tables.Count)
Console.WriteLine(ds.Tables(0).Rows.Count)
Console.WriteLine(ds.Tables(1).Rows.Count)
If I look at the output window, it will print 2 (tables), 10000 (rows in T(0)) and 6 (rows in T(1)). Not all DBProviders have this capability. Access for instance will choke on the SQL string. Other changes to the way your code is composed:
DBConnections and DBCommand objects need to be disposed. They allocate resources, so they need to be created, used and disposed to release those resources.
The Using block does that for us: The target objects are created at the start and closed and disposed at End Using.
The code above stacks or combines 2 such blocks.
The code fills a DataSet from the query, in this case creating 2 tables. Rather than copying the data from one container to another (like a control), you can use a DataTable as the DataSource:
cboDevName.DataSource = ds.Tables(0)
cboDevName.DisplayMember = "DevName" ' column names
cboDevName.ValueMember = "Id"
cboDevType.DataSource = ds.Tables(1)
cboDevType.DisplayMember = "DevType"
cboDevType.ValueMember = "DevCode"
The result will be all the rows from each table appearing in the respective combo control. Typically with this type of thing, you would want the ID/PK and the name which is meaningful to the user in the query. The user sees the friendly name (DisplayMember), which the code can easily access the unique identifier for the selection (ValueMember).
When using bound list controls, rather than using SelectedIndex and the SelectedIndexChanged event, you'd use SelectedValue and SelectedItem to access the actual data.
MSDN: Using Statement (Visual Basic)
You can use .net connector (download here)
Then you can install it and add it to your project (project -> references -> add -> browse).
Finally add import:
Imports MySql.Data.MySqlClient
So you'll be able to use this:
Dim connStr as String = "Server = localhost; Database = gen_database; Uid = root; Pwd ="
Dim SqlStr as String = "Select DevCompanyName from developer_name_table; Select DevType from development_type_table"
Dim ds As DataSet = MySqlHelper.ExecuteDataset(CnStr, SqlStr)
ds will contain two datatables: one for each query

vb.net mysql combobox show tables

I am new at programming, and I'm working on a basic VB.NET application that allows the user to select, insert, update, and delete various data tables from MySQL.
The trouble I'm having is, I need to populate a combobox with all the table names from one specific database, so that the user can select which database table to work with. I thought my code would work, but all I'm getting when I run the app is a blank combobox.
Could someone please tell me what's wrong with my code?
Thanks so much in advance!
Code:
Private Sub TableList_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles TableList.SelectedIndexChanged
Try
command = New MySqlCommand
dt = New DataTable
adapter = New MySqlDataAdapter
If (conn.State = ConnectionState.Closed) Then
setConnection()
End If
command.Connection = conn
command.CommandText = "SHOW TABLES"
adapter.SelectCommand = command
reader = command.ExecuteReader
'adapter.Fill(dt)
dt.Load(reader)
TableList.DataSource = dt
TableList.DisplayMember = "Tables_in_sampledata" 'What is displayed
TableList.ValueMember = "Tables_in_sampledata" 'The ID of the row
Catch ex As MySqlException
MessageBox.Show("Error1: " & ex.Message)
Finally
reader.Close()
conn.Close()
End Try
End Sub
Instead of SHOW TABLES, use the following query
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='YourDatabase';