How do I read HasRow then Update? - vb.net

Is it possible to read HasRow and then Update ?
This is the code what I have tried so far :
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
Dim sqlcmd As New MySqlCommand("SELECT * FROM tbl_online_attendance where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' ", conn)
Dim dr As MySqlDataReader
dr = sqlcmd.ExecuteReader
If dr.HasRows Then
Dim query As String
query = "UPDATE tbl_online_attendance SET out_time = '" & lvRealAtt.Items(itms).SubItems(2).Text & "' where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' "
sqlcmd.Connection = conn
sqlcmd.CommandText = query
sqlcmd.ExecuteNonQuery() 'It error in this part
Else
End If
But it give's me error saying:
There is already an open DataReader associated with this Connection which must be closed first
Please avoid commenting Use Parameters Your code is Prone to SQL injection attack

You should not have to check connection state if you keep your connections local to the method that they are used. Database objects like connections and commands need to be closed and disposed as soon as possible. Using...End Using blocks take care of this for you even if there is an error. Don't open a connection until directly before the .Execute....
Don't pull down data when you only need Count. .ExecuteScalar returns the first column of the first row of the result set, which in this case, is the Count. If you have a large table you need to look into If Exists which will stop as soon it finds a match whereas Count looks at the whole table.
Always use Parameters. Never concatenate strings to build sql queries to avoid sql injection. I had to guess at the datatypes of the parameters. Check your database to get the actual types and adjust the code accordingly.
Private Sub OPCode(ByVal itms As Integer)
Dim RowCount As Integer
Using conn As New MySqlConnection("Your connection string"),
sqlcmd As New MySqlCommand("SELECT Count(*) FROM tbl_online_attendance where employees_id = #id and in_time = #inTime;", conn)
sqlcmd.Parameters.Add("#id", MySqlDbType.Int32).Value = CInt(lvRealAtt.Items(itms).SubItems(0).Text)
sqlcmd.Parameters.Add("#inTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(1).Text
conn.Open()
RowCount = CInt(sqlcmd.ExecuteScalar)
If RowCount > 0 Then
sqlcmd.CommandText = "UPDATE tbl_online_attendance SET out_time = #outTime where employees_id = #id and in_time = #inTime;"
sqlcmd.Parameters.Add("#outTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(2).Text
sqlcmd.ExecuteNonQuery()
End If
End Using
End Sub

Every SqlDataReader needs to be closed before you could execute another query.
so i suggest you to separate the sqlreader and the update query, put the reader into a boolean function to check either a row with those parameters exist or not.
Private Function HasRow(ByVal employeeid As Integer, ByVal date as DateTime) As Boolean
HasRow = False
Dim reader As SqlDataReader
'do select query here
'use the if reader.Read if you want to
HasRow = reader.HasRows
reader.Close()
End Function
Call the function before updating, if it's True then proceed the update. Let's say we put it into a Update Sub.
Private Sub Update()
If HasRows(parameters here) Then
'update query here
End If
End Sub

Related

Cell not updated - VB.net, oledb

Ive been wrestling with the code below for a long time now, and just when i thought it works it doesnt, and it doesnt even give me an error.
Dim sql As String = "UPDATE " & table & " SET ArithmeticScore = #score WHERE DateAscending = " & todaysdate
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
connection.Open()
command.Parameters.Add("#score", OleDbType.Decimal).Value = score
MsgBox("score was added = " & score)
command.ExecuteNonQuery()
connection.Close()
End Using
End Using
todaysdate currently holds the value 27/04/2020 as date
conn holds the connection string, table holds the table name.
The messagebox outputs what it is meant to, with score having a decimal value that should be added into the table.
The purpose of this code is to update the ArithmeticScore column in the table, Where DateAscending = 27/04/2020. When the program is finished, and i check the database, the cell remains blank. Why could this be?
This is because executed query can not find required record.
Try to set correct type for sql parameter for DateAscending column.
Dim sql As String =
$"UPDATE {table} SET ArithmeticScore = #score WHERE DateAscending = #todaysdate"
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
command.Parameters.Add("#score", OleDbType.Decimal).Value = score
command.Parameters.Add("#todaysdate", OleDbType.Date).Value = DateTime.Now.Date
connection.Open()
Dim affectedRows As Integer = command.ExecuteNonQuery()
' Check or display that affectedRows is greater than zero
End Using
End Using

How to quick update MySQL table through a loop using VB.net

My code for updating mysql table having more than 2000 rows through a loop using VB.net is working fine but too slow. Is there any way to update it faster ? Anybody please help. Thanks. My code is given below.
Dim mysqlconn = New MySqlConnection
mysqlconn.ConnectionString = "server=localhost;user id=root;password=1234;database=Share"
mysqlconn.Open()
Dim adapter As New MySqlDataAdapter("SELECT * FROM name_list;", mysqlconn)
Dim datatable As New DataTable()
adapter.Fill(datatable)
Dim cmd As New MySqlCommand
cmd.Connection = mysqlconn
Dim sql As String
Dim i as integer = 0
While i <= datatable.Rows.Count - 1
Dim sy As String = datatable.Rows(i).Item(3).ToString.Trim
sql = "UPDATE Name_list Set Numerology = '" & "N-" & variable1 & " S- " & variable2 & "',FSTLetter = '" & variable3 & "',Timing = '" & vriable4 & "',P_Numerology = '" & variable5 & "' WHERE Symbol = '" & sy & "'"
sy = ""
cmd.CommandText = sql
cmd.ExecuteNonQuery()
i = i + 1
End While
adapter.Fill(datatable)
DataGridView1.DataSource = datatable
DataGridView1.Refresh()
Don't name variables the same as class names (DataTable, datatable) vb.net is case insensitive so it confuses intellisense.
Database connections and commands need to closed and disposed.
Using blocks do this for you even if there is an error.
You can set the connection string by passing it directly to the constructor of the connection. Likewise, you can set the command text and the connection by passing to the constructor of the command.
Don't open the connection until right before it is used. In this case we don't need a DataAdapter but if you are using one it is not necessary to open the connection at all. The .Fill method of the DataAdapter will open and close the connection. However if the DataAdapter finds an open connection it will leave it open.
To avoid confusion, I created 2 data tables. I used a single connection but I opened and closed it each time it is used. It is not disposed until the last End Using.
The first command retrieves only the sy column. Replace Column4_Name with the actual column name. We don't want to pull down data we don't need so no Select *.
Always use parameters to avoid sql injection which can damage your database. You need to check your database for the types of the fields. I had to guess. Each parameters value is set except sy which changes on each iteration.
No need to close the connection after the last Select command since the final End Using will close and dispose.
After the connection is closed we update the user interface.
Private Sub OPCode(variable1 As String, variable2 As String, variable3 As String, variable4 As String, variable5 As String)
Dim dtBeforeUpdate As New DataTable()
Dim dtAfterUpdate As New DataTable()
Using mysqlconn = New MySqlConnection("server=localhost;user id=root;password=1234;database=Share")
Using cmd As New MySqlCommand("SELECT Column4_Name FROM name_list;", mysqlconn)
mysqlconn.Open()
dtBeforeUpdate.Load(cmd.ExecuteReader)
mysqlconn.Close()
End Using
Using cmd As New MySqlCommand($"UPDATE Name_list Set Numerology = #Numerologh, FSTLetter = #FST, Timing = #Timing, P_Numerology = #P_Numerology WHERE Symbol = #sy ", mysqlconn)
cmd.Parameters.Add("#Numerology", MySqlDbType.String).Value = $"N-{variable1} S- {variable2}"
cmd.Parameters.Add("#FST", MySqlDbType.String).Value = variable3
cmd.Parameters.Add("#Timing", MySqlDbType.String).Value = variable4
cmd.Parameters.Add("#P_Numerology", MySqlDbType.String).Value = variable5
cmd.Parameters.Add("#sy", MySqlDbType.String)
mysqlconn.Open()
For Each row As DataRow In dtBeforeUpdate.Rows
cmd.Parameters("#sy").Value = row(0).ToString.Trim
cmd.ExecuteNonQuery()
Next
mysqlconn.Close()
End Using
Using cmd As New MySqlCommand("Select * From Name_list;", mysqlconn)
mysqlconn.Open()
dtAfterUpdate.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dtAfterUpdate
End Sub
Actually, I don't get it. It seems like you are updated the entire table with the same data. Do you expect the variable1, variable2 etc. to change somehow?
Don't know where your variable1, variable2, etc come from, but those look to be static, so your loop is somewhat pointless it would seem. You're updating every row in the loop to the exact same values (unless there's other code you're not showing), so just update the table without the loop:
Using con As New MySQLConnection
con.ConnectionString = "server=localhost;user id=root;password=1234;database=Share"
con.Open
Using cmd As New MySQLCommand
cmd.Connection = con
cmd.CommandText = "UPDATE Name_list Set Numerology = '" & "N-" & variable1 & " S- " & variable2 & "',FSTLetter = '" & variable3 & "',Timing = '" & vriable4 & "',P_Numerology = '" & variable5 & "'"
cmd.ExecuteNonQuery
End Using
End Using

Visual basic - Incrementing the score

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim READER As MySqlDataReader
Dim Query As String
Dim connection As MySqlConnection
Dim COMMAND As MySqlCommand
Dim item As Object
Try
item = InputBox("What is the item?", "InputBox Test", "Type the item here.")
If item = "shoe" Then
Dim connStr As String = ""
Dim connection As New MySqlConnection(connStr)
connection.Open()
Query = "select * from table where username= '" & Login.txtusername.Text & " '"
COMMAND = New MySqlCommand(Query, connection)
READER = COMMAND.ExecuteReader
If (READER.Read() = True) Then
Query = "UPDATE table set noOfItems = noOfItems+1, week1 = 'found' where username= '" & Login.txtusername.Text & "'"
Dim noOfItems As Integer
Dim username As String
noOfItems = READER("noOfItems") + 1
username = READER("username")
MessageBox.Show(username & "- The number of items you now have is: " & noOfGeocaches)
End If
Else
MsgBox("Unlucky, Incorrect item. Please see hints. Your score still remains the same")
End If
Catch ex As Exception
MessageBox.Show("Error")
End Try
I finally got the message box to display! but now my code does not increment in the database, can anybody help me please :D
Thanks in advance
After fixing your typos (space after the login textbox and name of the field retrieved) you are still missing to execute the sql text that updates the database.
Your code could be simplified understanding that an UPDATE query has no effect if the WHERE condition doesn't find anything to update. Moreover keeping an MySqlDataReader open while you try to execute a MySqlCommand will trigger an error in MySql NET connector. (Not possible to use a connection in use by a datareader). We could try to execute both statements in a single call to ExecuteReader separating each command with a semicolon and, of course, using a parameter and not a string concatenation
' Prepare the string for both commands to execute
Query = "UPDATE table set noOfItems = noOfItems+1, " & _
"week1 = 'found' where username= #name; " & _
"SELECT noOfItems FROM table WHERE username = #name"
' You already know the username, don't you?
Dim username = Login.txtusername.Text
' Create the connection and the command inside a using block to
' facilitate closing and disposing of these objects.. exceptions included
Using connection = New MySqlConnection(connStr)
Using COMMAND = New MySqlCommand(Query, connection)
connection.Open()
' Set the parameter value required by both commands.
COMMAND.Parameters.Add("#name", MySqlDbType.VarChar).Value = username
' Again create the reader in a using block
Using READER = COMMAND.ExecuteReader
If READER.Read() Then
Dim noOfItems As Integer
noOfItems = READER("noOfItems")
MessageBox.Show(username & "- The number of items you now have is: " & noOfItems )
End If
End Using
End Using
End Using

how validate if record not found on database in vb.net

how make sure if record not found when sql query using where not get the result.
i use this source and work for display record if record found, but i don't know how use "if then else" for change the "while"
Sub usercheck()
'Prepare Connection and Query
dbconn = New MySqlConnection("Server=localhost;Database=user_team;Uid=root;Pwd=")
strQuery = "SELECT * " & _
"FROM tb_team_user WHERE user_ip = '" & lip.Text & "'"
SQLCmd = New MySqlCommand(strQuery, dbconn)
'OPEN THE DB AND KICKOFF THE QUERY
dbconn.Open()
DR = SQLCmd.ExecuteReader
While DR.Read
tbteam.Text = DR.Item("user_team")
End While
End Sub
Before your while loop, you can add an if statement to see if there are any rows returned:
If DR.HasRows Then
' There was at least 1 row returned
Else
' There were no rows returned
End If

the user must match to the 3 fields

Dim elem As String
elem = "Grade School"
Dim v As Integer
v = 0
Dim con As New SqlConnection("SERVER=ANINGDZTS-PC;DATABASE=AEVS;Trusted_Connection = yes;")
Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM tbl_Voter WHERE Department, VotersID = '" & elem & "''" & txt_PwordElem.Text & "'AND Voted ='" & v & "'", con)
con.Open()
Dim sdr As SqlDataReader = cmd.ExecuteReader()
Try
If (sdr.Read() = False) Then
high()
Else
MessageBox.Show("WELCOME!")
elemBallot.Show()
Me.Hide()
End If
Catch EX As Exception
MsgBox(EX.Message)
End Try
End Sub
this code is not working, an error appear," An expression of non-boolean type specified in a context where a condition is expected, near ','."
Instead of trying to create your SQL query via concatenating strings, which is prone to errors, a much better way is to use parametrized query. Change your SqlCommand declaration to
Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM tbl_Voter WHERE Department = #Department AND VotersID = #VotersID AND Voted = #Voted", con)
cmd.Parameters.AddWithValue("#Department", elem)
cmd.Parameters.AddWithValue("#VotersID", txt_PwordElem.Text)
cmd.Parameters.AddWithValue("#Voted", v)
Bonus: Avoid SQL Injection
P.S. Please don't forget to close your Reader and Connection after the use.
P.P.S. If you simple need to make sure that specific row in table "tbl_Voter" exists or not based on your parameters (which is, judging by the code what you're doing) - using DataReader is overkill. Consider query like SELECT 1 FROM tbl_Voter ... and use of ExecuteScalar to check returned value for Nothing