Checking if the fund is sufficient - mysql

I am currently doing an ATM Management System, I want my program to check if the amount entered does not exceed the account's balance on database. Here is my code:
Dim w As Double
w = Val(txtwithdraw.Text)
adapter = New MySql.Data.MySqlClient.MySqlDataAdapter("SELECT `balance` FROM `jaagbank` WHERE
acctnum = '" & Form1.namebox.Text & "'", con)
dtable.Clear()
adapter.Fill(dtable)
If w > dtable.Rows.Count Then
MsgBox("Insufficient Balance")
txtwithdraw.Clear()
Return
End If

Decimal is a good datatype to used for money. Don't use the vb6 Val(). You can get unexpected results. Put Option Strict and Option Infer on. I used .TryParse to test the input in txtwithdraw. If it returns True, it puts the converted decimal value in WithdrawalAmount.
Keep your data objects local to the method where they are used. Connections and commands need to be closed and disposed. Using...End Using blocks handle this for us even if there is an error.
Always use parameters to avoid sql injection. If the code is running in Form1, do not qualify namebox with Form1. It seems a bit strange that a field named acctnum is not a number but a String containing a name. You will need to check your database for the correct datatype and field size. I had to guess.
Since you are retrieving a single piece of data, you can use .ExecuteScalar which will give you the first column of the first row.
Private Sub OPCode()
Dim WithdrawalAmount As Decimal
If Not Decimal.TryParse(txtwithdraw.Text, WithdrawalAmount) Then
MessageBox.Show("Please enter a valid withdrawal amount.")
Return
End If
Dim Balance As Object
Using con As New MySqlConnection(ConStr),
cmd As New MySqlCommand("SELECT `balance` FROM `jaagbank` WHERE acctnum = #Name;", con)
cmd.Parameters.Add("#Name", MySqlDbType.VarChar, 100).Value = Form1.namebox.Text
con.Open()
Balance = cmd.ExecuteScalar
End Using
If Balance Is Nothing Then
MessageBox.Show("Account not recognized.")
Return
End If
If WithdrawalAmount > CDec(Balance) Then
MsgBox("Insufficient Balance")
txtwithdraw.Clear()
Return
End If
End Sub

Related

How can I get the usernames in the account?

I'm making a VB.Net application which connects to a MySql database.
My application has many Accounts, and each account has several Users. I want to show this information, but the application just shows the first user of each account.
This is the code:
Public Function id(Label2 As String) As Double
Using connection = Getconnection()
connection.Open()
Using commandid = New MySqlCommand
commandid.Connection = connection
commandid.CommandText = "SELECT *FROM player.player
Where player.account_id=" & testString & V
Dim read = commandid.ExecuteReader
If read.HasRows Then
While read.Read
ActivateUser.namecharacter = read.GetString(2)
ActivateUser.job = read.GetString(3)
End While
read.Dispose()
Return True
Else
MessageBox.Show(" no ")
Return False
End If
connection.Close()
connection.Dispose()
End Using
End Using
End Function
How can I fix this to show all the users in the account?
Just create you connection in the method where you use it. Get rid of GetConnection just use a class level variable for the connection string.
Don't open a connection until directly before you use it.
You can include the command in the same using block by adding a comma at the end of the first line. Commands also need to be disposed. The command constructor can take the CommandText and the Connection as parameters.
What datatype is account_id in the database? I am going to guess it is a string type. Is V a variable or is it meant to be the string "V"? I am going to guess a hardcoded string. Where does testString come from? I am going to guess Label2 (terrible non-descriptive name) is teststring.
Never concatenate strings for you sql. Always use parameters.
A reader also needs to be closed and disposed so use Using blocks. The whole idea of accessing the database is to get in and out as quickly as possible. Don't set properties of ActivateUser and never show a message box. The user could have gone to lunch and your connection is left flapping in the breeze.
You have the datatype of your function as Double but your return statements have Booleans. Won't work.
It is not necessary to close and dispose the connection. The End Using does that.
Private ConStr As String = "Your connection string"
Public Function id(Label2 As String) As DataTable
Dim dt As New DataTable
Using connection As New MySqlConnection(ConStr),
commandid As New MySqlCommand("SELECT *FROM player Where account_id= #TestString;", connection)
commandid.Parameters.Add("#TestString", MySqlDbType.VarChar).Value = Label2 & "V"
connection.Open()
Using reader = commandid.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Then back in the User Interface code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt = id(Label2.Text)
If dt.Rows.Count > 0 Then
ActivateUser.namecharacter = dt(0)(2).ToString
ActivateUser.job = dt(0)(3).ToString
Else
MessageBox.Show(" no ")
End If
End Sub
This makes a good separation of from your database code.

Delete command using ID from DataGridView

I have data shown in DataGridView. I made a Button when selecting IDs in the grid the code below runs but I keep getting an error.
Dim cnx As New MySqlConnection("datasource=localhost;database=bdgeststock;username=root;password=")
Dim cmd As MySqlCommand = cnx.CreateCommand
Dim resultat As Integer
If ConnectionState.Open Then
cnx.Close()
End If
cnx.Open()
If grid.SelectedCells.Count = 0 Then
MessageBox.Show("please select the ids that u want to delete")
Else
cmd.CommandText = "delete from utilisateur where idu= #P1"
cmd.Parameters.AddWithValue("#P1", grid.SelectedCells)
resultat = cmd.ExecuteNonQuery
If (resultat = 0) Then
MessageBox.Show("error")
Else
MessageBox.Show("success")
End If
End If
cnx.Close()
cmd.Dispose()
How does this make sense?
cmd.Parameters.AddWithValue("#P1", grid.SelectedCells)
As you tagged this question WinForms, you are presumably using a DataGridView rather than a DataGrid (names matter so use the right ones). In that case, the SelectedCells property is type DataGridViewSelectedCellCollection. How does it make sense to set your parameter value to that? How is that going to get compared to an ID in the database?
If you expect to use the values in those cells then you have to actually get those values out. You also need to decide whether you're going to use a single value or multiple. You are using = in your SQL query so that means only a single value is supported. If you want to use multiple values then you would need to use IN and provide a list, but that also means using multiple parameters. I wrote an example of this type of thing using a ListBox some time ago. You can find that here. You could adapt that code to your scenario like so:
Dim connection As New SqlConnection("connection string here")
Dim command As New SqlCommand
Dim query As New StringBuilder("DELETE FROM utilisateur")
Select Case grid.SelectedCells.Count
Case 1
query.Append(" WHERE idu = #idu")
command.Parameters.AddWithValue("#idu", grid.SelectedCells(0).Value)
Case Is > 1
query.Append(" WHERE idu IN (")
Dim paramName As String
For index As Integer = 0 To grid.SelectedCells.Count - 1 Step 1
paramName = "#idu" & index
If index > 0 Then
query.Append(", ")
End If
query.Append(paramName)
command.Parameters.AddWithValue(paramName, grid.SelectedCells(index).Value)
Next index
query.Append(")")
End Select
command.CommandText = query.ToString()
command.Connection = connection
SelectedCells is a collection of cells
so it never can be only one id, so you have to guess which was you want or only allow one row to be selected
grid.SelectedCells(0).Value.ToString()
Or you have to program a loop to delete all selected rows

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.

Visual Basic 2010 - Display multiple MySql queries to different datagridviews on a Form

Good day,
I'm developing a project where I use Visual Basic 2010 and MySql. The function of the project is to perform sports timing services. I'm semi-knowledgeable with programming in the above environments, and when I struggle, I Google for answers and it serves me well 99% of the time.
My problem is this: I have a database with tables for each sports event. All the data gets captured and all the functionality is working as intended. I would now like to display the results of this race on a Form using four GridViews (4 is the most race distances that are allowed). These results need to be separately displayed (using different queries) for each race distance (4 at most).
I have code to display the results, but this populates all four gridviews with the same data. Here is my code:
Private Sub ListResults()
Dim query As String = "SELECT RaceNo, FirstName, LastName, RaceDistance, RaceTime FROM " & frmMain.EventCode & _
" WHERE NOT ISNULL(RaceTime) AND RaceDistance = '" & frmMain.RaceDistance1 & "' ORDER BY RaceDistance ASC, RaceTime ASC;"
Dim connection As New MySqlConnection(frmMain.connStr)
Dim da As New MySqlDataAdapter(query, connection)
Dim ds As New DataSet
Try
If da.Fill(ds) Then
dgvLoadResultsA.DataSource = ds.Tables(0)
dgvLoadResultsB.DataSource = ds.Tables(0)
dgvLoadResultsC.DataSource = ds.Tables(0)
dgvLoadResultsD.DataSource = ds.Tables(0)
End If
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
da = Nothing
connection.Close()
connection = Nothing
End Try
End Sub
I understand that I need to produce four different queries (which I'm able to do), but I'm not sure how to send the results of those queries to the different gridviews. I don't seem to fully understand how to send the result of my queries to different tables in the dataset. I can just create the code by running the sub with different parameters and variables, but thought that there is a better way of doing this.
Any assistance in this matter would be highly appreciated.
Thank you in advance.
What you need to do is use a different DataSet per Query.
Personally I'd split your Query code into a separate Function taking the Event and Distance as Parameters and returning your DataTable;
Private Function GetResults(ByVal EventCode As Integer, ByVal RaceDistance As Integer) As DataTable
Dim query As String = "SELECT RaceNo, FirstName, LastName,
RaceDistance, RaceTime
FROM " & EventCode & _
" WHERE NOT ISNULL(RaceTime)
AND RaceDistance = '" & RaceDistance & "'
ORDER BY RaceDistance ASC, RaceTime ASC;"
Dim connection As New MySqlConnection(frmMain.connStr)
Dim da As New MySqlDataAdapter(query, connection)
Dim ds As New DataSet
Try
If da.Fill(ds) Then
Return ds.Tables(0)
End If
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
da = Nothing
connection.Close()
connection = Nothing
End Try
End Sub
I've assumed your Data Types here, you will of course need to modify this to use the correct Data Types.
Then you can attach your DataSources using;
dgvLoadResultsA.DataSource = GetResults(EventCodeA, RaceDistanceA)
dgvLoadResultsB.DataSource = GetResults(EventCodeB, RaceDistanceB)
dgvLoadResultsC.DataSource = GetResults(EventCodeC, RaceDistanceC)
dgvLoadResultsD.DataSource = GetResults(EventCodeD, RaceDistanceD)
Ideally you'd also pass in your Connection String to the GetResults Function, then your Function is Unit Testable, but I'll leave that decision to you.
Of course, you should ideally check that your Function returns a valid DataTable before attaching. But I didn't want to over complicate the solution!

How can I query by an value which is segmented, as 123-456-789 in mysql in vb.net?

My problem is, when I query by a usual ID, like number with no segments = 1234567890, it works nicely.
But I need to query by some kind of segmented values or ID as = 123-4567-890, when I try by 123-4567-890 this id it does not query anything in mysql although in the database this 123-4567-890 ID is present.
So what is the possible solution to search by segmented value in mysql in VB.NET
Here is below, my trying codes in vb
Public Sub student()
textbox1.text= "123-4567-890"
Try
dbConn()
Dim myAdapter As New MySqlDataAdapter("Select studentID, batchID, studentStatus from student where studentID= " & textbox1.text, ServerString)
Dim myDataTable As New DataTable
myAdapter.Fill(myDataTable)
If myDataTable.Rows.Count > 0 Then
vrSID = myDataTable.Rows(0).Item("studentID")
vrRecBatchID = myDataTable.Rows(0).Item("batchID")
vrAttendanceStatus = myDataTable.Rows(0).Item("studentStatus")
If vrSID = vrIDD Then
If vrAttendanceStatus = "Active" Then
Console.Beep()
batchRoutine()
Else
led3()
Console.Beep()
End If
End If
Else
Console.Beep()
teacher()
End If
Catch ex As Exception
Console.Beep()
MsgBox ("Error")
End Try
End Sub
When you are running into problems, the easiest way to solve them is to break things down to the simplest scenario. So instead of complicating things with table adapters and data tables, see what happens when you just send MySQL the query you 'think' works correctly.
So start out by seeing if you can get this to work, then go from there:
Dim sql As String = "select id from mytable where id = '123-4567-890'"
Using cnx As New MySqlConnection("connection_string")
Using cmd As New MySqlCommand(sql, cnx)
cnx.Open()
Using reader As MySqlDataReader = cmd.ExecuteReader()
Debug.Assert(reader.Read(), "No results")
Trace.WriteLine(reader.GetValue(reader.Item(0)))
End Using
End Using
End Using
if the column is in-fact a sort of student ID column (not social security I would expect), and the table has it without special characters, I would pre-strip the extra formatting (hyphens) from the string and pass the CLEANED value to the query as a parameter to get results.
Also, by explicitly adding the query string Plus the text box value, you are leaving yourself WIDE OPEN to sql injection. Look into Parameterized queries (my guess is it would be an object something like MySqlDataParameter data type.)