VB.net data retrieval and display - mysql

So, for some reason I can't work out I think the below is only retrieving the 1st letter of the value within the column I'm trying to search. (Note: the database is called m1 and contains 11 columns in total).
I tested the query first in SQL Admin and it worked properly (I think).
I then wrote this myself using documentation, I think I've more that likely made a mistake somewhere..
Dim hostnameQuery As String = "SELECT `HOSTNAME` FROM `m1` WHERE 1"
Dim SQLConnection As New MySqlConnection(My.Settings.connStr)
Dim cmd As New MySqlCommand(hostnameQuery, SQLConnection)
Try
SQLConnection.Open()
cmd.ExecuteNonQuery()
Dim reader As MySqlDataReader
reader = cmd.ExecuteReader
While reader.Read
main.Label64.Text = (reader.GetChar(0))
End While
Catch ex As Exception
MsgBox(ex.Message.ToString)
Finally
SQLConnection.Close()
End Try
I added this to a button click so when I click the button only the letter 'M' appears but the value is 'M1'
What have I done wrong?

That's because you requested only a character. Try using GetString() instead of GetChar() :
main.Label64.Text = (reader.GetString(0))

There are many things that can be improved in your code.
First of all, you can remove the condition WHERE 1, because it means "EVERYTHING" so it is not useful.
Secondly, you can avoid calling cmd.ExecuteNonQuery() because it is usually used to run an instruction that does not return anything (like INSERT).
Finally, if you are interested only to the first returned row, you can avoid the While loop and use cmd.ExecuteScalar() instead.
To summarize, instead of:
cmd.ExecuteNonQuery()
Dim reader As MySqlDataReader
reader = cmd.ExecuteReader
While reader.Read
main.Label64.Text = (reader.GetChar(0))
End While
simply do this:
main.Label64.Text = Convert.ToString(cmd.ExecuteScalar())

Related

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

Reader if and else statement

I am practicing programming in visual basic
I have 2 forms in visual basic.
The first form has a command button that will show the input data from the 2nd form
The second form has a textbox where I need to input a data and save it.
The data that I input in the 2nd form stores it in MySQL
the 1st form has a command button named "Show my Grade" and if I click that I want to display the Form 2 and show me the grade. It does work however if I didn't input any grade and then I click the "show my grade" button it crashes I don't know the error. I tried using the code "if READER.HasRows Then:
but still it won't work
also tried if READER.Read then:
else MessageBox.Show("there is no grade input at the moment")
Please help.
This is my current code in the command button in form 1.
Me.Visible = False
Form2.Show()
MySqlConn = New MySqlConnection
MySqlConn.ConnectionString = "server=localhost;userid=root;password=qwerty;database=ssg"
Dim COMMAND As New MySqlCommand
Dim READER As MySqlDataReader
MySqlConn.Open()
COMMAND.Connection = MySqlConn
COMMAND.CommandText = "select grade from gradetable"
READER = COMMAND.ExecuteReader
Form2.TextBox1.Text = READER("grade")
End Sub
It works as long as I input a grade first, however if I didn't input any grade it crashes.
If I click the "Show my grade" button in form 1 without inputting a grade in form 2 I would like to just display a message saying "You still have no grade at the moment"
Please help.
The Using statement with a matching End Using. This is in place of Dim. It ensures that your objects are properly closed and disposed of even if there is an error. This is especially important for connections which should be closed as soon as possible.
I used the constructor of the connection to pass in the connection string. Setting the property is fine. This just saves a line of code.
Same idea with the command constructor. It can take the command text and the connection. Saves a little typing.
You had the right idea; using .HasRows. You just needed to add the READER.Read to get to the first record as explained in comments by jmcilhinney.
Private Sub GetGrade()
Using MySqlConn As New
MySqlConnection("server=localhost; userid=root; password=qwerty; database=ssg")
Using COMMAND As New MySqlCommand("select grade from gradetable", MySqlConn)
MySqlConn.Open()
Using READER As MySqlDataReader = COMMAND.ExecuteReader
If READER.HasRows Then
READER.Read()
Form2.TextBox1.Text = READER("grade")
Else
MessageBox.Show("Sorry, no grade yet.")
End If
End Using
End Using
End Using
End Sub

Redefining/Re-setting parameters in MySQL query

I have the following code for inserting data into a table using a MySQL query in VB.NET
Dim MySqlCmdStr = "INSERT INTO tb_idlink(id1,id2) " &
"VALUES (#par1,#par2)"
MySqlCmd.CommandText = MySqlCmdStr
Dim checkedItem As Object
For Each checkedItem In CheckedListBox_1.CheckedItems
Try
MySqlCmd.Connection = MySqlConn
With MySqlCmd
.Parameters.AddWithValue("#par1", currentID)
.Parameters.AddWithValue("#par2", checkedItem.ToString())
End With
MySqlConn.Open()
MySqlCmd.ExecuteNonQuery()
MySqlConn.Close()
Catch ex As MySqlException
MessageBox.Show(ex.Message)
End Try
Next
My problem is if I have more than one box checked in CheckedListBox_1 then on the second loop an exception that says something like "parameter #par1 already defined". Is there a way I can re-define it? I'm not entirely familiar with the whole API.
Also, I'm not 100% sure if looping it is the best way to do this, but it's the first thing that popped into my head. Feel free to suggest an alternative way of doing this.
You dont redefine the parameters, you just supply a new value:
Dim SQL = "INSERT INTO tb_idlink (id1,id2) VALUES (#par1,#par2)"
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(SQL, dbcon)
' define the parameter names and types
cmd.Parameters.Add("#par1", MySqlDbType.Int32)
cmd.Parameters.Add("#par2", MySqlDbType.Int32) ' ????
dbcon.Open()
For Each checkedItem In CheckedListBox1.CheckedItems
' provide the parameter values
cmd.Parameters("#par1").Value = currentID
cmd.Parameters("#par2").Value = Convert.ToInt32(checkedItem)
cmd.ExecuteNonQuery()
Next
End Using
End Using
Your code appears to reuse a global connection, that is ill-advised. The above uses Using blocks to create, use and and dispose of the DbConnection and DbCommand objects in the smallest scope possible
You should favor Add rather than AddWithValue so you can specify the datatype rather than forcing the the DB Provider guess and reduce the chance of data type mismatch errors.
These datatypes are a guess; CurrentId is not defined anywhere and given the names, both seem to be integers not strings.

Select statement have got error in VB.Net with mysql

The error message is also available in another threads but in my case it's different.
Object reference not set to an instance of an object. When querying the following select statement. What is the problem inside?
Dim con As New MySqlConnection(ConString)
Dim sql As String
Dim idno As Integer
sql = "select client_id from car_rent where car_id = #carid"
cmd.Parameters.AddWithValue("#carid", carid.Text.Trim)
cmd = New MySqlCommand(sql, con)
idno = cmd.ExecuteScalar()
If (idno > 0) Then
MsgBox("The Car is already Rented!", MsgBoxStyle.Exclamation, "Car Rental System")
Return
End If
I don't see you opening the connection anywhere. use
con.open()
Switch the order of these two lines
cmd = New MySqlCommand(sql, con)
cmd.Parameters.AddWithValue("#carid", carid.Text.Trim)
Also the line in which you execute the command seems to be working because you are using Option Strict Off, and I suggest to change to Option Strict On. In the short term you have to solve many problems but it allows better coding practices
idno = CType(cmd.ExecuteScalar(), Integer)
However, if the command above doesn't find any record matching the parameter passed, ExecuteScalar returns Nothing and so you need to test for this situation
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing Then
idno = CType(result, Integer)
And, of course, the connection should be opened before, so summarizing everything
Dim sql = "select client_id from car_rent where car_id = #carid"
Using con As New MySqlConnection(ConString)
Using cmd = New MySqlCommand(sql, con)
con.Open()
cmd.Parameters.AddWithValue("#carid", carid.Text.Trim)
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing Then
Dim idno = CType(result, Integer)
If (idno > 0) Then
MsgBox("The Car is already Rented!", MsgBoxStyle.Exclamation, "Car Rental System")
Return
End If
End If
End Using
End Using
Well probably is enough to test for Nothing on the result of ExecuteScalar to take your decision unless you need the idno variable for other purposes.

vb net SQl query problem

im trying to retrieve some data using a reader in vb.net. I dont have any issue retrieving certain columns of the data for each row but i want to retrieve all data in each row. I've tried a couple of different things with the getstring() command but it isnt working and i cant seem to find any help googling the issue. my code is this
Private Function QueryDown(ByVal queryString)
Dim returnInfo As New StringBuilder
Try
Dim newQuery As String() = Split(queryString, ":")
For Each Query In newQuery
Dim cmd As New MySqlCommand(Query, connection1)
Dim reader As MySqlDataReader
reader = cmd.ExecuteReader()
While reader.Read()
For a = 0 To reader.FieldCount
Dim strng As String = reader.GetString(a)
returnInfo.Append(strng & ",")
Next
returnInfo.Append(";")
End While
reader.Close()
Next
Catch ex As Exception
console("Error with MySQL: " & ex.Message)
Return ex.Message
End Try
Return returnInfo.ToString
End Function
sorry the error i get when using this code is
There is already an open DataReader
associated with this Connection which
must be closed first
but if i change getstring(a) to getstring(1) everything is fine, im confused.
any help here would be great, i want to formatted code to come back column,column,coloumn;nextrow, as you can see (i hope). Because each of my table has a different amount of coloumns and i want to be able to use the same function for each one. thanks again.
Upper limit is reader.FieldCount - 1 not reader.FieldCount in:
For a = 0 To reader.FieldCount - 1
when a reaches reader.FieldCount there is an exception => reader.Close() is not executed => I suppose you call this function (or another) to open a new reader with the same connection => error.
When you call getstring(1) its working because 1 is within [0, FieldCount-1]
Update:
As #Zach Green said, try to always use using when ever possible which is a replacement for try...finally{ .Dispose() }: the dispose in finallyis applied to object beeing "used" and calling for DataReader/DataConnection it will call .Close() for you.