Visual basic - Incrementing the score - vb.net

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

Related

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

How do I read HasRow then Update?

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

"Operation must be an updateable query" VB.Net OleDB for Excel

Ive been trying to find a solution for this problem without any success:
I'm using VB.NET and I need to read and update records from an Excel file. I use the OleDB API for that. It works fine for all the reading, but impossible to write to the file (Update or Insert queries)
Here is what I have:
My connection string:
Public connString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\...\Resources\attempt.xls;Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'"
Select query that works fine:
Dim checkQuery = "SELECT * FROM [Sheet1$] WHERE [TravellerPN] = #T"
Try
Using connection As New OleDb.OleDbConnection(Form.connString)
Dim checkCommand As New OleDbCommand(checkQuery, connection)
checkCommand.Parameters.Add("#T", OleDbType.VarChar).Value = PN
connection.Open()
Dim reader As OleDbDataReader = checkCommand.ExecuteReader()
Dim path As String = ""
While reader.Read()
path = reader("Datapath").ToString
End While
reader.Close()
MsgBox(PN & " " & DP & " " & path,,)
If a record for the part number entered doesnt exist, and nothing is returned, insert a new line
If path = "" Then
Dim addQuery = "INSERT INTO [Sheet1$] ([TravellerPN],[Datapath]) VALUES (#T, #D)"
Dim addCommand As New OleDbCommand(addQuery, connection)
addCommand.Parameters.Add("#T", OleDbType.VarChar).Value = PN
addCommand.Parameters.Add("#D", OleDbType.VarChar).Value = DP
Dim rows As Integer = addCommand.ExecuteNonQuery()
And this was where it returns the error.
MsgBox(rows & " row added!",, "") 'Never diplayed
And other query that doesn't work either:
Else 'If does exist, confirm replacement'
Dim replaceResponse = MsgBox("A path already exists for " & PN & "." & vbNewLine & "Do you want to replace " & path & " with " & DP & "?", MsgBoxStyle.YesNo, "Overwrite previous datapath?")
Dim replaceQuery = "UPDATE [Sheet1$] SET [Datapath] = #D WHERE [TravellerPN]=#T"
Dim replaceCommand As New OleDbCommand(replaceQuery, connection)
replaceCommand.Parameters.Add("#D", OleDbType.VarChar).Value = DP
replaceCommand.Parameters.Add("#T", OleDbType.VarChar).Value = PN
Dim rows As Integer = replaceCommand.ExecuteNonQuery()
MsgBox(rows & " row updated!",, "")
End If
connection.Close()
End Using
I've tried to fix the issue: it could be caused by permissions, so I authorized even guests accounts to modify my folder.
If it were a ReadOnly mode in the connection: I tried adding Mode=ReadWrite but my connection String didn't work after that. (That option seems only available for ADO connections?)
I tried running the app as administrator
And finally, I'm posting this here hoping to get some help.
Sorry or the long post, I was trying to give all the elements that could potentially be a problem.
Thanks.

MysqlDataReader.Read stuck on the last record and doesnt EOF

i confused why mySqlDataReader.Read stuck on the last record and doesnt EOF ..
Here's my private function for executeSql :
Private Function executeSQL(ByVal str As String, ByVal connString As String, ByVal returnRecordSet As Boolean) As Object
Dim cmd As Object
Dim objConn As Object
Try
If dbType = 2 Then
cmd = New MySqlCommand
objConn = New MySqlConnection(connString)
Else
cmd = New OleDbCommand
objConn = New OleDbConnection(connString)
End If
'If objConn.State = ConnectionState.Open Then objConn.Close()
objConn.Open()
cmd.Connection = objConn
cmd.CommandType = CommandType.Text
cmd.CommandText = str
If returnRecordSet Then
executeSQL = cmd.ExecuteReader()
executeSQL.Read()
Else
cmd.ExecuteNonQuery()
executeSQL = Nothing
End If
Catch ex As Exception
MsgBox(Err.Description & " #ExecuteSQL", MsgBoxStyle.Critical, "ExecuteSQL")
End Try
End Function
And this is my sub to call it where the error occurs :
Using admsDB As MySqlConnection = New MySqlConnection("server=" & rs("server") & ";uid=" & rs("user") & ";password=" & rs("pwd") & ";port=" & rs("port") & ";database=adms_db;")
admsDB.Open()
connDef.Close()
rs.Close()
'get record on admsdb
Dim logDate As DateTime
Dim str As String
str = "select userid, checktime from adms_db.checkinout in_out where userid not in (select userid " &
"from adms_db.checkinout in_out join (select str_to_date(datetime,'%d/%m/%Y %H:%i:%s') tgl, fid from zsoft_bkd_padang.ta_log) ta " &
"on ta.fid=userid and tgl=checktime)"
Dim rsAdms As MySqlDataReader = executeSQL(str, admsDB.ConnectionString, True)
Dim i As Integer
'This is where the error is, datareader stuck on the last record and doesnt EOF
While rsAdms.HasRows
'i = i + 1
logDate = rsAdms(1)
'save to ta_log
str = "insert into ta_log (fid, Tanggal_Log, jam_Log, Datetime) values ('" & rsAdms(0) & "','" & Format(logDate.Date, "dd/MM/yyyy") & "', '" & logDate.ToString("hh:mm:ss") & "', '" & logDate & "')"
executeSQL(str, oConn.ConnectionString, False)
rsAdms.Read()
End While
'del record on admsdb
str = "truncate table checkinout"
executeSQL(str, admsDB.ConnectionString, False)
End Using
i'm new to vbnet and really have a little knowledge about it,, please help me,, and thank you in advance..
The issue is that you're using the HasRows property as your loop termination expression. The value of that property never changes. Either the reader has rows or it doesn't. It's not a check of whether it has rows left to read, so reading has no effect.
You are supposed to use the Read method as your flag. The data reader begins without a row loaded. Each time you call Read, it will load the next row and return True or, if there are no more rows to read, it returns False.
You normally only use HasRows if you want to do something special when the result set is empty, e.g.
If myDataReader.HasRows Then
'...
Else
MessageBox.Show("No matches found")
End If
If you don't want to treat an empty result set as a special case then simply call Read:
While myDataReader.Read()
Dim firstFieldValue = myDataReader(0)
'...
End While
Note that trying to access any data before calling Read will throw an exception.

Storing ID from SQL result

Im running the following code to tell if a user excists on a database - standard stuff. Obviously once the code is run a boolean true or false will be returned if there is a result. If a result is found i want to store the ID of the said result. Can anyone tell me how'd id go about doing this?
code:
Username = txtUserName.Text
Password = txtPassword.Text
dbConnInfo = "PROVIDER=Microsoft.Jet.OLEDB.4.0; Data Source = C:\Users\Dave\Documents\techs.mdb"
con.ConnectionString = dbConnInfo
con.Open()
Sql = "SELECT * FROM techs WHERE userName = '" & Username & "' AND '" & Password & "'"
LoginCommand = New OleDb.OleDbCommand(Sql, con)
CheckResults = LoginCommand.ExecuteReader
RowsFound = CheckResults.HasRows
con.Close()
If RowsFound = True Then
MsgBox("Details found")
TechScreen.Show()
Else
MsgBox("Incorrect details")
End If
There are a lot of problems with the code snippet you posted. Hopefully, I can help you correct these problems.
In order to load the ID of the result you'll want to use SqlCommand.ExecuteScalar() as this is optimized to pull back one result from Sql.
As to what is wrong with your code, you're wide open to Sql Injection attacks and you should be using Parametrized Queries as shown in my sample below.
Public Function AddProductCategory( _
ByVal newName As String, ByVal connString As String) As Integer
Dim newProdID As Int32 = 0
Dim sql As String = _
"INSERT INTO Production.ProductCategory (Name) VALUES (#Name); " _
& "SELECT CAST(scope_identity() AS int);"
Using conn As New SqlConnection(connString)
Dim cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar)
cmd.Parameters("#Name").Value = newName
Try
conn.Open()
newProdID = Convert.ToInt32(cmd.ExecuteScalar())
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
Return newProdID
End Function
Source: MSDN