Strange issue when retrieving data from my database - mysql

When reading data from a table, one of my numerical values returns as a -1, rather than a value given by the user.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim conn As New MySqlConnection("server=localhost;user=root;database=new_project;port=3306;password=********;")
conn.Open()
Dim command As New MySqlCommand("SELECT * FROM students;", conn)
Dim dataSet As New DataSet()
Dim dataAdapter As New MySqlDataAdapter()
dataAdapter.SelectCommand = command
dataAdapter.Fill(dataSet, "students")
Dim dataTable As DataTable = dataSet.Tables("students")
For x As Integer = 0 To dataTable.Rows.Count - 1
Dim newStudent As New Student
newStudent.intIDNum = dataTable.Rows(x).Item("idNumber")
newStudent.strFirstName = dataTable.Rows(x).Item("firstName")
newStudent.strLastName = dataTable.Rows(x).Item("lastName")
newStudent.chrGender = dataTable.Rows(x).Item("gender")
newStudent.dateDOB = dataTable.Rows(x).Item("dateOfBirth")
newStudent.intAge = CInt(Today.Year - newStudent.dateDOB.Year)
newStudent.intYearGroup = dataTable.Rows(x).Item("yearGroup")
newStudent.intSkillLevel = dataTable.Rows(x).Item("skillLevel")
studentList.Add(newStudent)
lstStudents.Items.Add(newStudent.nameConcat(newStudent.strFirstName, newStudent.strLastName))
Next
conn.Close()
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
End Try
End Sub
When reading the value "skillLevel", it should read between 1 and 4, but instead it reads a -1. This hasn't occurred with any data added directly to the database through MySQL, but when using the method in my program, it seems this issue appears.
Dim newStudent As New Student
newStudent.strFirstName = txtForename.Text
newStudent.strLastName = txtSurname.Text
newStudent.dateDOB = dtpStudentDOB.Value
If rdbMale.Checked = True Then
newStudent.chrGender = "M"
Else
newStudent.chrGender = "F"
End If
newStudent.intAge = newStudent.calcAge(dtpStudentDOB.Value)
newStudent.intSkillLevel = cmbSkillLevel.SelectedItem
newStudent.intYearGroup = cmbYearGroup.SelectedItem
newStudent.intIDNum = CInt(txtStudentID.Text)
Dim conn As New MySqlConnection("server=localhost;user=root;database=new_project;port=3306;password=********;")
Try
conn.Open()
Dim command As MySqlCommand = New MySqlCommand
command.Connection = conn
command.CommandText = "INSERT INTO Students VALUES(#IdNumber, #firstName, #lastName, #gender, #dateOfBirth, #yearGroup, #skillLevel);"
command.Prepare()
command.Parameters.AddWithValue("#IdNumber", newStudent.intIDNum)
command.Parameters.AddWithValue("#firstName", newStudent.strFirstName)
command.Parameters.AddWithValue("#lastName", newStudent.strLastName)
command.Parameters.AddWithValue("#gender", newStudent.chrGender)
command.Parameters.AddWithValue("#dateOfBirth", newStudent.dateDOB)
command.Parameters.AddWithValue("#yearGroup", newStudent.intYearGroup)
command.Parameters.AddWithValue("#skillLevel", newStudent.intSkillLevel)
command.ExecuteNonQuery()
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
Finally
conn.Close()
End Try
This is the section of code where a student is added to the system. What exactly could be causing this error to appear?
For reference, the main form I add in the data uses an enumeration:
Private Enum SkillLevels As Integer
One = 1
Two = 2
Three = 3
Four = 4
End Enum
And then I link it to the dropdown: cmbSkillLevel.DataSource = System.Enum.GetValues(GetType(SkillLevels))

The obvious possibility is that no selection was made in the SKILL-LEVEL dropdown and that is why you are getting -1, you can check if a selection has been made in the dropdown by ensuring it is not -1
For example your skills drop down may look like this
<select id="SkillLevel">
<option value="0" selected="selected">Please Select</option>
<option value="1">Low</option>
<option value="2">Medium</option>
<option value="3">High</option>
<option value="4">Very-High</option>
</select>
If no selection is made the default value returned will be zero (0)
And you can check for valid values by looking for returned values > 0
As far as I can remember if you omit the selected="selected" then the returned value will be -1

I think I had misinterpreted #tolanj's comments. It appears that when loading my data, the system couldn't read my skillLevel column. To fix it, I changed newStudent.intSkillLevel = row.Item("skillLevel") to newStudent.intSkillLevel = SByte.Parse(row.Item("skillLevel")).

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

VB.Net Delete Selected Row in DataGridView MySql

This the code that I use. The message box is appearing but when I select yes, the selected row is not deleted at the datagridview and database.
Private Sub Delete2_Click_1(sender As Object, e As EventArgs) Handles Delete2.Click
MySqlConn = New MySqlConnection
MySqlConn.ConnectionString = "server=127.0.0.1;userid=root;password=;database=equipment"
Try
If Me.DataGridView2.Rows.Count > 0 Then
If Me.DataGridView2.SelectedRows.Count > 0 Then
Dim intStdID As Char = Me.DataGridView2.SelectedRows(0).Cells("asset_code").Value
'open connection
If Not MySqlConn.State = ConnectionState.Open Then
MySqlConn.Open()
End If
'delete data
Dim cmd As New MySqlCommand
cmd.Connection = MySqlConn
cmd.CommandText = "DELETE * FROM equipment.equipment" & intStdID
Dim res As DialogResult
res = MsgBox("Are you sure you want to DELETE the selected Row?", MessageBoxButtons.YesNo)
If res = Windows.Forms.DialogResult.Yes Then
cmd.ExecuteNonQuery()
Else : Exit Sub
End If
'refresh data
Load_table()
'close connection
MySqlConn.Close()
End If
End If
Catch ex As MySqlException
End Try
Look at this line:
cmd.CommandText = "DELETE * FROM equipment.equipment" & intStdID
It attempts to append the ID value from the selected cell to the SQL statement. However, it seems like this is just the ID value. You also need the WHERE ID= portion for the query.
Moreover, it's using this ID value in the query in the wrong way. It's NEVER okay to use string concatenation to include data in a query. You must use parameterized queries.
The code below demonstrates this, as well as several other better patterns for this method, with the caveat that I had to guess as some names and types from your database.
Private Sub Delete2_Click_1(sender As Object, e As EventArgs) Handles Delete2.Click
If Me.DataGridView2.Rows.Count = 0 OrElse Me.DataGridView2.SelectedRows.Count = 0 Then
Exit Sub
End If
Dim res As DialogResult = MsgBox("Are you sure you want to DELETE the selected Row?", MessageBoxButtons.YesNo)
If res <> DialogResult.Yes Then Exit Sub
Dim intStdID As Char = Me.DataGridView2.SelectedRows(0).Cells("asset_code").Value
Dim SQL as String = "DELETE * FROM equipment.equipment WHERE equipment.StdID= #AssetCode"
Using con As New MySqlConnection("server=127.0.0.1;userid=root;password=;database=equipment"), _
cmd As New MySqlCommand(SQL, con)
cmd.Parameters.Add("#AssetCode", MySqlDbType.VarChar, 1).Value = intStdID
con.Open()
cmd.ExecuteNonQuery()
End Using
Load_table()
End Sub

Hide part of String.Format within a ComboBox.Item

Is it possible to hide part of String.Format?
This my code:
'Select Product'
Try
MysqlConn.Close()
MysqlConn.Open()
Dim Query As String
Query = "select id, name,id_maker, id_types from product ORDER BY name ASC"
COMMAND = New MySqlCommand(Query, MysqlConn)
READER = COMMAND.ExecuteReader
While READER.Read
Dim sName = READER.GetString("name")
Dim sMaker = READER.GetString("id_maker")
Dim sTypes = READER.GetString("id_types")
Dim sId = READER.GetString("id")
'ComboBox1.Items.Add(sName)'
ComboBox1.Items.Add(String.Format("{0}|{1}|{2}|{3}", sName, sMaker, sTypes, sId))
End While
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
MysqlConn.Dispose()
End Try
'Select Product'
I want to hide {3} which is sId in the ComboBox, because later I need to use a query where the ComboBox1.Text is used and the id is necessary.
Maybe you could change the way you are assigning the data to the ComboBox.
First thing to do is change the query and use CONCAT:
SELECT id, CONCAT(name,'|',id_maker,'|',id_types) AS value FROM product ORDER BY name ASC
I would also implement Using:
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.
You also don't need the READER. Instead load the data into a DataTable and assign that to the .DataSource property on the ComboBox.
Your code would look something like this:
Using con As New MySqlConnection(connectionString)
cmd As New MySqlCommand("SELECT id, CONCAT(name,'|',id_maker,'|',id_types) AS value FROM product ORDER BY name ASC", con)
con.Open()
Dim dt As New DataTable
dt.Load(cmd.ExecuteReader())
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "value"
ComboBox1.ValueMember = "id"
End Using
You can now get the id with this bit of code:
ComboBox1.SelectedValue.ToString()
And you can get the text with this bit of code:
ComboBox1.Text
Ok i use now that and works
Dim connetionString As String = Nothing
Dim connection As MySqlConnection
Dim command As MySqlCommand
Dim adapter As New MySqlDataAdapter()
Dim ds As New DataSet()
Dim i As Integer = 0
Dim sql As String = Nothing
'connetionString = "Data Source=ServerName;Initial Catalog=databasename;User ID=userid;Password=yourpassword"
'sql = "select id,name from product"
sql = "SELECT id, CONCAT(name,' | ',id_maker,' | ',id_types) AS value FROM product ORDER BY name ASC"
'connection = New MySqlConnection(connetionString)
connection = New MySqlConnection(ConfigurationManager.ConnectionStrings("xCollectibles.My.MySettings.xcollectiblesConnectionString").ToString)
Try
connection.Open()
command = New MySqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
connection.Close()
ComboBox1.DataSource = ds.Tables(0)
ComboBox1.ValueMember = "id"
ComboBox1.DisplayMember = "value"
Catch ex As Exception
MessageBox.Show("Can not open connection ! ")
End Try
Thanks you..

VB.NET ComboBox SelectedIndex from MySQL

so I have done with show data form my database MySQL to ComboBox.. I'm using this code:
Private Sub Get_Product()
Connection()
Dim command As New MySqlCommand
Dim reader As MySqlDataReader
Dim query As String = "SELECT * FROM product, writer, publisher WHERE product.writer = writer.writer AND product.publisher = publisher.publisher AND code = " & throwCode & " ORDER BY code"
Dim queryWriter As String = "SELECT DISTINCT writer, writer_name FROM writer ORDER BY writer_name"
Dim dataAdapter As New MySqlDataAdapter(queryWriter, conn)
Dim dataSet As New DataSet
dataAdapter.Fill(dataSet, "writer")
Try
command = New MySqlCommand(query, conn)
reader = command.ExecuteReader
While reader.Read
TextBoxISBN.Text = reader("isbn")
TextBoxTitle.Text = reader("title")
TextBoxPage.Text = reader("page")
With (ComboBoxWriter)
.Items.Add("Select")
.DataSource = dataSet.Tables("writer")
.DisplayMember = "writer_name"
.ValueMember = "writer"
.SelectedIndex = 0 **// Give atention to this code**
End With
TextBoxYear.Text = reader("year")
TextBoxCategory.Text = reader("category")
TextBoxCallNumber.Text = reader("call_number")
TextBoxWeight.Text = reader("weight")
TextBoxPurchasePrice.Text = reader("purchase_price")
TextBoxSellingPrice.Text = reader("selling_price")
TextBoxDiscount.Text = reader("discount")
TextBoxDescription.Text = reader("description")
TextBoxTag.Text = reader("tag")
TextBoxPusatPenerbit.Text = reader("pusat_penerbit")
TextBoxMrican.Text = reader("mrican")
TextBoxPaingan.Text = reader("paingan")
If (Not IsDBNull(reader("picture"))) Then
Dim byteImage() As Byte = reader("picture")
Dim tempImage As New System.IO.MemoryStream(byteImage)
PictureBoxPicture.Image = Image.FromStream(tempImage)
End If
End While
conn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
In my code, I give some comment and bold to show you what I want to do.
So I have a writer code in product an writer code in writer (writer code named as writer), and I join the table to show writer name from writer code. But in ComboBox I want to show all of writer for editing but the default value is index of the writer that same like in product table.
1
2
If you see my first image that have a writer name Sutarjo Adisusilo but when I view it and want to use it as a default value in combobox that show A. Kardiyat Wiharyanto as indexvalue number 0..
I need help how to change the default value to be same like the picture number 1
Thanks
I've updated this answer to an easier method. Double check the column names though.
ComboBoxWriter.SelectedIndex = ComboBoxWriter.FindStringExact(reader("writer_name"))

Add row in DataGridView with data-bound control

I have a form with two datagridview that gets items from a mysql database.
My goal is to click an item of the first DGV and get it inserted into the second, then (pressing a button) update the table on the database.
The problem is that I cannot add a row (I get exception: Can not add rows programmatically to the set of rows in DataGridView when data-bound control) and, if I programmatically fill the last row (the row for manual inserting) the value is not acquired.
But if I fill manually the last row and press the "update button" the database become updated.
This is the code of "CellContentClick"
Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim DvgRow% = e.RowIndex
Dim DvgCol% = e.ColumnIndex
Dim SelCell$ = Me.DataGridView1.Item(DvgCol, DvgRow).Value.ToString.Trim()
Dim IntColSel$ = Me.DataGridView1.Columns(DvgCol).HeaderText
Dim Dgv2Rows% = Me.DataGridView2.RowCount
If IntColSel.ToUpper = "REGION" Then
'Here I get the value in the last row but is ignored being updated
Me.DataGridView2.Item(0, Me.DataGridView2.RowCount - 1).Value = SelCell
'Here I get exception
Me.DataGridView2.Rows.Add()
End If
End Sub
This is the code to fill the 2nd DGV:
Private Sub GetInDGV2(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button13.Click
With DataGridView2
.DataSource = Nothing
.Rows.Clear()
.Columns.Clear()
End With
cnString = "datasource=" + Server_Name + ";username= " + UserDB + _
";password=" + Password + ";database=" + Database_Name + ""
sqlQRY2 = "Select Region from regions"
conn = New MySqlConnection(cnString)
Try
conn.Open()
da2 = New MySqlDataAdapter(sqlQRY2, conn)
Dim cb2 As MySqlCommandBuilder = New MySqlCommandBuilder(da2)
da2.Fill(ds2, "regions")
DataGridView2.DataSource = ds2
DataGridView2.DataMember = "regions"
Catch ex As Common.DbException
MsgBox(ex.ToString)
Finally
conn.Close()
End Try
End Sub
I saw this question aswered but I wasn't able to translate from C an test it.
Thanks for any help.
As DataGridview2 is bounded to a DataTable2, you cannot directly modify the cells. You must update DataTable2 by adding a new DataRow. Once added, DataGRidView2 will be automatically refreshed.
To get the RowValues required to populate your new DataRow, you may access to DataTable1 DataRow. To Get the DataRow of underlying DataTable1, corresponding to the current row of dataGridView1:
Dim selectedrow As DataRow = DirectCast(DataGridView1.CurrentRow.DataBoundItem, DataRowView).Row ;
Then create a new DataRow in DataTable2 with the values got from slectedrow.
Dim dataTable2 As DataTable = ds2("Regions")
Dim newrow As DataRow = dataTable2.NewRow()
For i As Integer = 0 To selectedrow.Count - 1
newrow(i) = selectedrow(i)
Next
dataTable2.Rows.Add(newrow)