Fetch SQL records without going through each row - mysql

Context:
I have around 50 records of names with their fingerprints saved in a database that will be needed for their daily time-in/time-out using a fingerprint scanner.
The code:
Dim conn As New MySqlConnection("...database_details")
Dim cmd As New MySqlCommand
Private Sub FetchRecords(sender As Object, e As IZKFPEngXEvents_OnCaptureEvent) Handles ZkFprint.OnCapture
'fingerprint sample from the scanner, returns a BASE64 format
Dim fp = e.aTemplate
Using conn
conn.Open()
cmd = conn.CreateCommand()
With cmd
.CommandType = CommandType.Text
'fprint stores varchar data type
.CommandText = "SELECT id,name,reg_fprint FROM tbl_emp"
End With
Dim dr as MySqlDataReader = cmd.ExecuteReader()
While dr.Read
'converts the fprint into BASE64
Dim fpFromDB = ZkFprint.DecodeTemplate1(dr.GetValue(1))
'compares fp to fpFromDB; returns true if match otherwise false
Dim result As = ZkFprint.VerFinger(fpFromDB, fp)
If result = True Then
lbName.Text = dr.GetValue(1)
Else
MessageBox.Show("Fingerprint not found")
End If
End While
End Using
End Sub
The problem:
When I scan a finger to time in/out, the MessageBox.Show("Fingerprint not found") line will trigger X-1 times before my lbName.Text changes to the matching record. This is because dr.Read() reads the first row until I find the record.
What I want:
Is there a way for me to get the record without going through each row?
What I tried:
I removed the Else statement, which solved my problem but leads me to another problem: it does not provide any feedback if a finger is not registered.
If result = True Then
lbName.Text = dr.GetValue(1)
End If
EDIT:
Thanks for the inputs, I appreciate it. I also manage to come up with a solution after playing with the code a few times thanks to #Shadow below the commments. I replaced the While Loop with a For Loop and put the data in a DataTable so I can easily go through them. I also used the recordCount as a reference if a record does not exists.
Dim fp = e.aTemplate
Dim dt As New DataTable
Dim recordCount As Integer
Using conn
conn.Open()
cmd = conn.CreateCommand()
With cmd
.CommandType = CommandType.Text
'fprint stores varchar data type
.CommandText = "SELECT id,name,reg_fprint FROM tbl_emp"
End With
Dim da As New MySqlDataAdapter(cmd)
da.Fill(dt)
For recordCount = 0 To dt.Rows.Count - 1
Dim result As = ZkFprint.VerFinger(dt.Rows(recordCount).Item(2).ToString, fp)
If result = True Then
lbName.Text = dt.Rows(recordCount).Item(1).ToString
Exit For
End If
Next
If recordCount = dt.Rows.Count Then
MessageBox.Show("Fingerprint not found")
End If
End Using

You may consider comparing the column fild while converting to base64
Dim conn As New MySqlConnection("...database_details")
Dim cmd As New MySqlCommand
Private Sub FetchRecords(sender As Object, e As IZKFPEngXEvents_OnCaptureEvent) Handles ZkFprint.OnCapture
'fingerprint sample from the scanner returns a BASE64 format
Dim fp = e.aTemplate
Using conn
conn.Open()
cmd = conn.CreateCommand()
With cmd
.CommandType = CommandType.Text
'fprint stores varchar data type
.CommandText = "SELECT id,name,reg_fprint FROM tbl_emp WHERE TO_BASE64(reg_fprint)=#reg_fprint"
.Parameters.Add(New MySqlClient.MySqlParameter("#reg_fprint", fp))
End With
Dim dr as MySqlDataReader = cmd.ExecuteReader()
If dr.Read
lbName.Text = dr.GetValue(1)
lbName.refresh() 'To update label text
Else
MessageBox.Show("Fingerprint not found")
End If
End Using
End Sub
But again you could change this block
If result = True Then
lbName.Text = dr.GetValue(1)
End If
to
If result = True Then
lbName.Text = dr.GetValue(1)
lbName.Refresh() 'Update the label
End If

Related

How to select all column value in mysql with VB.NET

I have table with two columns : "Total" and "Returned" I am trying to take all column values from both but it not work with me. It takes only the first row in the column I want total values in the column
My code :
Private Sub TotalTextBox_TextChanged(sender As Object, e As EventArgs) Handles TotalTextBox.TextChanged
Dim str As String = "Server=localhost;Port=3306;Database=testdb;Uid=root;Pwd=password"
Using net As New MySqlConnection(str)
Dim totalnet As String = "Select * from testata where Qty_Returned and Total"
Dim cm As New MySqlCommand(totalnet, net)
net.Open()
Dim rdnet As MySqlDataReader = cm.ExecuteReader()
If rdnet.Read() Then
Label16.Text = rdnet.GetString(12) - rdnet.GetString(11)
Else
End If
End Using
End Sub
Glad you got it working. Just a few suggestions...
Turn on Option Strict for this and all your code.
Comments are inline.
Private Sub testdataDataGridView_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles testataDataGridView.DataBindingComplete
'A Using...End Using block will ensure that your objects that use unmanages
'resources are closed and disposed event if there is an error in the code
Using con As New MySqlConnection("Server=localhost;Port=3306;Database=testdb; Uid=root;Pwd=1234")
'A command object constructor can take an query string and connection as arguments
Using cmd As New MySqlCommand("select sum(Qty_Returned) FROM testdata", con)
'Open the connection at the last possible minute
con.Open()
Dim sqlresult = cmd.ExecuteScalar
Label16.Text = sqlresult.ToString
End Using
Using cmg As New MySqlCommand("select sum(Total) FROM testgdata", con)
Dim sqlresult2 = cmg.ExecuteScalar
Label10.Text = sqlresult2.ToString
End Using
End Using
Label18.Text = (CInt(La
End Sub
Not sure why this code is in this event.
I got the solution with this code:
Private Sub testdataDataGridView_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles testataDataGridView.DataBindingComplete
Dim con As New MySqlConnection("Server=localhost;Port=3306;Database=testdb; Uid=root;Pwd=1234")
Dim cmd As New MySqlCommand
Dim cmg As New MySqlCommand
con.Open()
cmd.Connection = con
cmd.CommandText = "select sum(Qty_Returned) FROM testdata"
Dim sqlresult As Object
sqlresult = cmd.ExecuteScalar
Dim str1 As String
str1 = sqlresult
Label16.Text = str1
cmg.Connection = con
cmg.CommandText = "select sum(Total) FROM testgdata"
Dim sqlresult2 As Object
sqlresult2 = cmg.ExecuteScalar
Dim str2 As String
str2 = sqlresult2
Label10.Text = str2
Label18.Text = Label10.Text - Label16.Text
End Sub

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

vb 2010 mysql insert record operation inserts a blank record but no data is inserted

I am trying to develop a utility in vb 2010, which will store values from Datagridview control to a mysql table
Steps
1) Datagrid cell values are stored in an array
2) Array values are used .AddWithValue() function
Present status: Only a blank record is inserted. Data is missing.
Please refer to following code.
Function insertRec()
'dgExistingProject is datagridview control embedded on the form
Dim ServerString As String = "Server=pnserver;User ID=root;
Password=; Database=prayer_net"
Dim Arr(RCount) As String
Dim SQLConn As MySqlConnection = New MySqlConnection
SQLConn.ConnectionString = ServerString
dim I as Integer
For I = 0 To RCount
Arr(I) = dgExistingProject.Rows(I).Cells(1).Value
Next
Try
Dim dt As Date = DateTime.Now.ToString("yyyy/MM/dd
HH:mm:ss")
Dim projName as Integer=Arr(4)
Using sqlCommand As New MySqlCommand
With sqlCommand
.CommandText = "INSERT INTO dyn_dwg_register
(file_name,file_location,dwg_description,
project_id,created_by, created_on)" & _
" values (#file_name, #file_location, #dwg_description, #project_id, #created_by, #created_on)"
.CommandType = CommandType.Text
.Connection = SQLConn
.Parameters.AddWithValue("#file_name", Arr(0))
.Parameters.AddWithValue("#file_location", Arr(1))
.Parameters.AddWithValue("#dwg_description", Arr(2))
.Parameters.AddWithValue("#project_id", ProjName)
.Parameters.AddWithValue("#created_by", Arr(4))
.Parameters.AddWithValue("#created_on", dt)
End With
Try
SQLConn.Open()
If SQLConn.State = ConnectionState.Open Then
Dim ID As Integer = sqlCommand.ExecuteNonQuery()
End If
Catch ex As Exception
MsgBox(ex.Message.ToString)
Finally
SQLConn.Close()
End Try
End Using
Catch e As Exception
MsgBox (e.Message.ToString)
End Try
End Function
Rajendra Nadkar
i had written a code in C# where i had to store data from a datagrid to SQL database. I used the following code. I think it will help you.
string sqlquery = "UPDATE TableName set ColumnName1=#param1 where ColumnName2=#param2";
using (OleDbCommand Cmd = new OleDbCommand(sqlQuery, dbCon))
{
Cmd.Parameters.AddWithValue("#param1", Convert.ToDouble(dataGridView1[1, index].Value));
Cmd.Parameters.Add(new OleDbParameter("#param2", OleDbType.VarWChar)).Value = "somevalue";
updateDbCmd.ExecuteNonQuery();
updateDbCmd.Parameters.Clear();
}
Funny, I changed the field name prefix # to ? and things became smooth. In an earlier question in Feb 11, Stelian Matei suggested this edit, though later on Giezel Esteves reversed it. (Original question asked by user1176607 in Feb '10)
I guess I need to refer to documentation more thoroughly. Anyways I am giving the working code here if you or anybody interested in it.
Dim qry As String = "INSERT INTO dyn_dwg_register (`file_name` , `file_location`, `dwg_description`, `project_id`, `created_by`)" & _
" values (?file_name, ?file_location, ?dwg_description, ?project_id, ?created_by)"
Dim sqlCommand As MySqlCommand
sqlCommand = New MySqlCommand(qry, SQLConn)
sqlCommand.CommandType = CommandType.Text
With sqlCommand
.Parameters.AddWithValue("?file_name", Arr(0))
.Parameters.AddWithValue("?file_location", Arr(1))
.Parameters.AddWithValue("?dwg_description", Arr(2))
.Parameters.AddWithValue("?project_id", ProjName)
.Parameters.AddWithValue("?created_by", Arr(2))
End With

Loop through Database table and get all values of each record in turn

I need to get all the values of each record in a table, this is so I can then add them to a text file log, a record per line, and then delete them from the database. I'm new to this and have searched how to add SQL query results to an array or a generic list, but I don't fully understand them.
All I have so far is:
Private Sub btnClearAll_Click(sender As Object, e As EventArgs) Handles btnClearAll.Click
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\Application Programming\Project\Issue Logger\Database\IssueLoggerDB.accdb"
Dim strSQl = "TRUNCATE TABLE CurrentJobs"
Dim commandInsert As New OleDbCommand
commandInsert.CommandText = strSQl
commandInsert.Connection = conn
commandInsert.Connection.Open()
commandInsert.ExecuteNonQuery()
Me.ReportViewer1.RefreshReport()
End Sub
This is for a Uni project, and above is how we have been to shown to do it, however nothing I have found while researching looks similar.
Feel free to use this procedure:
Private Sub DataTableToTextFile()
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\Application Programming\Project\Issue Logger\Database\IssueLoggerDB.accdb"
Using conn As OleDbConnection = New OleDbConnection(connString)
Dim dt As New DataTable
conn.Open()
'Change the query. It's not a good practice to use '*' in your select queries. Please, use the column names instead.
Dim dataAdapter As New OleDbDataAdapter("SELECT * FROM CurrentJobs", conn)
dataAdapter.Fill(dt)
'Change the path to your desired path
Dim exportPath As String = "C:\Logs\"
Dim exportFileName As String = "log.txt"
'If directory does not exists, create it
If Not Directory.Exists(exportPath) Then
Directory.CreateDirectory(exportPath)
End If
'Write data into the text file
Dim writer As New StreamWriter(exportPath + exportFileName)
Try
Dim sb As New StringBuilder
For Each row As DataRow In dt.Rows
sb = New StringBuilder
For Each col As DataColumn In dt.Columns
sb.Append(row(col.ColumnName))
Next
writer.WriteLine(sb.ToString())
Next
Catch ex As Exception
Throw ex
Finally
If Not writer Is Nothing Then writer.Close()
End Try
'Finally clean database table
Dim strSQl = "Delete From CurrentJobs"
Dim commandDelete As New OleDbCommand(strSQl, conn)
'execute
commandDelete.ExecuteNonQuery()
'close connection
conn.Close()
End Using
End Sub

Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'.

when i try to select an item in the ListView that has no image in my database this error shows Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'. i tried to put up some code like isDBNull or DBNull but it's applicable.
here's my code:
Private Sub LvPeople_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LvPeople.SelectedIndexChanged
If LvPeople.SelectedItems.Count > 0 Then
Dim connstring As String = "server = localhost; user id = root; database = db; password = root"
Dim Sql As String = "select * from candidate where idn='" & LvPeople.SelectedItems(0).Text & "'"
Dim conn As New MySqlConnection(connstring)
Dim cmd As New MySqlCommand(Sql, conn)
Dim dr As MySqlDataReader = Nothing
conn.Open()
dr = cmd.ExecuteReader()
dr.Read()
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
conn.Close()
End If
End Sub
End Class
the error points here:
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
i really have no idea what to put here. just a newbie here.
Since it is possible that there is no image data previously saved for a row, you need to test for DBNull before trying to use it:
If IsDBNull(dr("photo")) = False Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
Else
' maybe display a "no Photo Available" stock image
End If
Note that this DBNull test is different than the one Steve is using. IsDBNull is a language function while the one he is using is a method of the DataReader object, which is also why there are different requirements. Yet a third way would be to compare it to System.DbNull:
If DBNull.Value.Equals(dr("photo")) = False Then
...
End If
Use the DataReader method IsDBNull, but this method requires the position of the field in the IDataRecord used by the reader, so you need to call also GetOrdinal with the name of the field to check
(Links point to the Sql Server version but they are the same for MySql)
Private Sub LvPeople_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LvPeople.SelectedIndexChanged
If LvPeople.SelectedItems.Count > 0 Then
Dim connstring As String = "...."
Dim Sql As String = "select * from candidate where idn=#id"
Using conn = new MySqlConnection(connstring)
Using cmd = new MySqlCommand(Sql, conn)
conn.Open()
cmd.Parameters.AddWithValue("#id", LvPeople.SelectedItems(0).Text)
Using dr = cmd.ExecuteReader()
if dr.Read() Then
if Not dr.IsDbNull(dr.GetOrdinal("photo")) Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
End If
End Using
End Using
End Using
End If
End Sub