Error on Search Button - vb.net

I searched on some codes on how to do a Search Button in VB.net. But somehow, it won't work because of an error. And simply because, I cannot understand its algorithm and function. Newbie here. Anyway, here is the code for the search button:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myConnection.Open()
crd.Clear()
fn.Clear()
ln.Clear()
Dim str As String
str = "SELECT * FROM tblReg WHERE (Code = '" & src.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
End While
myConnection.Close()
End Sub
And the error was on:
dr = cmd.ExecuteReader
And VB said:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: No value given for one or more required parameters.

One should not follow online tutorials that teach very bad code. That code is very bad because it contains SQL injection and leaves database objects opened.
You should rewrite your code as follows:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myConnection.Open()
crd.Clear()
fn.Clear()
ln.Clear()
Using cmd = New OleDbCommand("SELECT * FROM tblReg WHERE Code = ?", myConnection)
cmd.CommandType = CommandType.Text
With cmd.Parameters.Add(Nothing, OleDbType.VarChar, 50)
.Direction = ParameterDirection.Input
.Value = src.Text
End With
Using dr = cmd.ExecuteReader()
While dr.Read()
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
End While
End Using
End Using
myConnection.Close()
End Sub
You have to use question marks in place of parameters because you are using OleDbCommand that does not support named parameters.
Change OleDbType.VarChar to your actual column type.

Is this the link where you get the code?
http://www.visual-basic-tutorials.com/ReadFromAccess.htm
Kindly do not get the code read each data on the output shows and also check this part of the code.
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
are you sure crd,fname,lname are the name of your fields in your table? pls check it and also what is the field type of code? is it a text or INT that is Auto Increment? or just an INT? no matter what it is change your code.
from
str = "SELECT * FROM tblReg WHERE (Code = '" & src.Text & "')"
to
str = "SELECT * FROM tblReg WHERE Code =" & src.Text
Updated
I suggest better read or follow the whole instruction based on link where you get your code. I suggest do the same as what the link said create the same and when the program runs with no error then incorporate it with your program beacuse I tried it using VB.NET and Access and it worked Im sure you dont read it. Do this and Im sure you will not just get the code you need you will also learn.

Related

error regular comes Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, MyBase.Activated
con.Close()
con.Open()
str = "select * from customer where CustomerID='" & ComboBox1.Text & "'"
cmd = New OleDbCommand(str, con)
da.SelectCommand = cmd
If IsNumeric(ComboBox1.Text) Then
cmd.CommandText = str = "select * from customer where CustomerID=#cid"
cmd.Prepare()
cmd.Parameters.AddWithValue("cid", ComboBox1.Text)
Dim dr As OleDbDataReader = cmd.ExecuteReader()
Try
If dr.Read() Then
TextBox1.Text = dr.GetValue(1)
TextBox2.Text = dr.GetValue(2)
TextBox3.Text = dr.GetValue(3)
TextBox4.Text = dr.GetValue(4)
TextBox5.Text = dr.GetValue(5)
dr.Close()
End If
Catch ex As Exception
MsgBox("", ex.Message)
dr.Close()
Finally
con.Close()
End Try
End If
Your code has several issues.
You did not provide your complete Combobox1_SelectedIndexChanged method. At least the last line that ends the method is missing.
You are reusing a connection. It is better practice to create a new connection (and dispose it afterwards) each time you need it. (Connection pooling might already reuse connections in the background.)
You have an exception handling mechanism that doesn't cover all your logic that can throw exceptions.
You are using two approaches to pass the SQL command text to the command object. One approach should suffice.
You call the Prepare method before you add your parameters to the command object. Apart from the fact that calling Prepare probably is not explicitly needed, I guess it should be called after you have added your parameters to the command object.
You are using the AddWithValue method to add parameters to your command object. That is evil.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, MyBase.Activated
'Better to use explicit column names instead of * here, especially if you use `GetValue` with a numeric index when mapping the query results to your textboxes.
Dim str As String = "select * from customer where CustomerID=#cid"
Try
Using con As New OleDbConnection("<connection string here>"), cmd As New OleDbCommand(str, con)
con.Open()
'Assuming here that CustomerID in the customer table is of type integer
cmd.Parameters.Add("#cid", OleDbType.Integer).Value = Integer.Parse(ComboBox1.Text)
Using dr As OleDbDataReader = cmd.ExecuteReader()
If dr.Read() Then
'Instead of using magical (ordinal) numbers, it would be better to use GetOrdinal as well: dr.GetValue(dr.GetOrdinal("fieldName"))
TextBox1.Text = dr.GetValue(1)
TextBox2.Text = dr.GetValue(2)
TextBox3.Text = dr.GetValue(3)
TextBox4.Text = dr.GetValue(4)
TextBox5.Text = dr.GetValue(5)
End If
'Perhaps you also want to include an Else block (in which case the database query did not return any results) to clear the textboxes?
End Using
End Using
Catch ex As Exception
MsgBox("", ex.Message)
'Closing any ADO.NET objects will be done automatically when they are disposed (when the Using block goes out of scope).
End Try
End Sub
Obviously, I have not tested the code above, since I do not have a fitting test environment for it. Please let me know if this code causes any issues you cannot solve yourself.
You have two Sql statements in your code.
1:
str = "select * from customer where CustomerID='" & ComboBox1.Text & "'"
2:
cmd.CommandText = str = "select * from customer where CustomerID=#cid"
You should get rid of #1 - delete that line of code and change #2 to be:
cmd.CommandText = "select * from customer where CustomerID=#cid"

Search button not responding

I created a search button to query my MS Access database and display the results but whenever I type in the ID and click search button it does nothing.
Everything else is working, it copies data from the VB form and stores it in the MS Access database but the search button does not query the database and retrieve the data.
Below is my code for the search button:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Dim found As Boolean
Try
cm = New OleDb.OleDbCommand
With cm
.Connection = cn
.CommandType = CommandType.Text
.CommandText = "SELECT* FROM tblInfo WHERE (ID = #ID & txtFind.Text = #ID)"
dr = .ExecuteReader
End With
While dr.Read()
found = True
txtFirst1.Text = dr("Pfirst").ToString
txtMid1.Text = dr("Pmiddle").ToString
txtLast1.Text = dr("Plast").ToString
txtAdd1.Text = dr("Paddress").ToString
txtPhone1.Text = dr("Pphone").ToString
txtContact1.Text = dr("Pcontact").ToString
End While
cn.Close()
Exit Sub
If found = False Then MsgBox("Patient ID not found!", MsgBoxStyle.Critical)
dr.Close()
Catch ex As Exception
End Try
How can I solve this?
The issue is the attempt to pass the value of txtFind.Text into the command.
You want to use parameters:
With cm
.Connection = cn
.CommandType = CommandType.Text
.CommandText = "SELECT * FROM tblInfo WHERE ID = ?"
.Parameters.Add("#ID", OleDbType.[Type]).Value = txtFind.Text
dr = .ExecuteReader
End With
Note that I have used OleDbType.[Type]. You will want to replace this with the data type you have specified for column ID.
It also looks like you have missed opening the connection before calling ExecuteReader():
cn.Open()
I would consider implementing Using:
Sometimes your code requires an unmanaged resource, such as a file handle, a COM wrapper, or a SQL connection. A Using block guarantees the disposal of one or more such resources when your code is finished with them. This makes them available for other code to use.
Here is some sample code:
Using con As New OleDbConnection(connectionString),
cmd As New OleDbCommand("SELECT * FROM tblInfo WHERE ID = ?", con)
con.Open()
cmd.Parameters.Add("#ID", OleDbType.[Type]).Value = txtFind.Text
dr = cmd.ExecuteReader()
...
End Using

Vb.net db issue

I'm writing a calorie counter tool for my girlfriend...
But I've run in to an issue I really cant figure out...
I have place in my script where I would wanna take some information out from my db...
The specific place in the script thats teasing, is the one that will take out data from a row called "antal" from a table called "items".
One place in my script, I call "navn" from items, and it works perfect...
This other place, it gives me the error that there isn't any data in the row!
My code looks so far like this:
Imports System.Data.OleDb
Private Sub ins_kat_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ins_kat.SelectedIndexChanged
Dim Con = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Privat\MCC\mccdb.mdb")
Con.Open()
Dim command As OleDbCommand = New OleDbCommand("SELECT * FROM items WHERE kat = '" & ins_kat.Text & "' ORDER BY id DESC", Con)
Dim read As OleDbDataReader = command.ExecuteReader()
ins_mad.Items.Clear()
While read.Read()
ins_mad.Items.Add(read.Item("navn")) '<---- This place works!!!
End While
Con.Close()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim ialt_c_counter As String
Dim ialt_c_counter_conv As Decimal
Dim ialt_c_counter_conv2 As Decimal
Dim ialt_counter As String
Dim ialt_final As Decimal
Dim Con = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Privat\MCC\mccdb.mdb")
Con.Open()
Dim command1 As OleDbCommand = New OleDbCommand("SELECT * FROM food WHERE dag = '" & stat_dag.Text & "' AND maaned = '" & stat_maaned1.Text & "' AND aar = '" & stat_aar1.Text & "'", Con)
Dim read1 As OleDbDataReader = command1.ExecuteReader()
While read1.Read()
ialt_c_counter = read1.Item("antal")
ialt_c_counter_conv = System.Convert.ToDecimal(ialt_c_counter)
Dim commandX As OleDbCommand = New OleDbCommand("SELECT * FROM items", Con)
Dim reader As OleDbDataReader = commandX.ExecuteReader()
ialt_counter = reader.Item("antal") '<--- THIS ONE is giving me the error!!
ialt_c_counter_conv2 = System.Convert.ToDecimal(ialt_counter)
ialt_final = (ialt_c_counter_conv / 100 * ialt_c_counter_conv2) + ialt_final
End While
Con.Close()
MsgBox(ialt_final)
End Sub
End Class
By now, I want a MsgBox telling me the result of my algorithm, but I don't even get that far cause of the error message...
I guess the error you see is
InvalidOperationException: Invalid attempt to read when no data is present.
You never call Read() on the OleDbDataReader called reader.
Note how you use a While loop to call Read() for read and read1, but not reader (bad variable names, btw).

Show SQL Column Item in VB.NET TextBox

I want a specific value of an SQL Database column to appear in a textbox, but there is an error with my code which appears to be at this line:
Dim lrd As MySqlDataReader = cmd.ExecuteReader()
Imports MySql.Data.MySqlClient
Public Class Main
Dim conn As MySqlConnection
Private Sub Main_Load(sender As Object, e As EventArgs) Handles Me.Load
conn = New MySqlConnection()
conn.ConnectionString = "server='127.0.0.1';user id='root';Password='test';database='snipper'"
Try
conn.Open()
Catch myerror As MySqlException
MsgBox("Error Connecting to Database. Please Try again !")
End Try
Dim strSQL As String = "SELECT * FROM snippets"
Dim da As New MySqlDataAdapter(strSQL, conn)
Dim ds As New DataSet
da.Fill(ds, "snippets")
With ComboBox1
.DataSource = ds.Tables("snippets")
.DisplayMember = "title"
.SelectedIndex = 0
End With
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title=" & cbSnippets.Text)
cmd.Connection = conn
Dim lrd As MySqlDataReader = cmd.ExecuteReader()
While lrd.Read()
txtCode.Text = lrd("snippet").ToString()
End While
End Sub
What may be wrong?
PLEASE USE PARAMETERISED QUERIES
Your actual problem originates from this line:
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title=" & cbSnippets.Text)
Supposing I enter "This is a test" into the text box, the SQL becomes
SELECT snippet
FROM snippets
WHERE title=This is a test
With no quotes around the text, it should be:
SELECT snippet
FROM snippets
WHERE title='This is a test'
However, if I were to write "''; DROP TABLE Snippets; -- " In your text box you may find yourself without a snippets table!.
You should always use parameterised queries, this is safer and more efficient (it means query plans can be cached and reused so don't need to be compiled each time);
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title = #Title")
cmd.Parameters.AddWithValue("#Title", cbSnippets.Text)
Dim lrd As MySqlDataReader = cmd.ExecuteReader()
Try changing this line :
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title=" & cbSnippets.Text)
to :
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title='" & cbSnippets.Text & "'")
Note the quotes around the string you'l be searching for. You could aswell use the like comparison too :
Dim cmd = New MySqlCommand("SELECT snippet FROM snippets where title like '%" & cbSnippets.Text & "%'")
The % symbol acts as a wildcard. In this case, that would look for any string containing the searched text instead of string being exactly the same as the searched text.

while loop only displaying 1 item

I am using a while loop to populate a second combo based on the value of the first combobox selection. What is happening however, is that the loop is only displaying 1 item in the second combobox instead of about 20. If I set breakpoint on the while loop I can see that all items are being calculated but just not appearing in the combobox.
I would be grateful if someone could point my basic newbie error. Many thanks
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'"
Dim cmd As New OleDb.OleDbCommand
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
While dr.Read()
If (dr.HasRows) Then
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End If
End While
cmd.Dispose()
dr.Close()
End Sub
The Text property of the combo box contains only what is displayed for the selected item. You need to add the items to the Items collection:
cmbDept.Items.Add(CStr(dr("Name")))
The combo boxes, list boxes etc. display items by calling their ToString() method. Therefore calling CStr should not even be necessary:
cmbDept.Items.Add(dr("Name"))
You are inserting a value in the SQL statement by concatenating strings. If you are just using your program for yourself, this is okay; however, on productive environments this is dangerous. Someone could enter a value that terminates the SELECT statement and introduces another malicious statement. E.g. a DELETE statement that deletes a whole table. This is called a SQL injection attack.
There are two ways to deal with this:
1) Escape the string:
sql = "SELECT * FROM Dep WHERE Cust = '" & s.Replace("'", "''") & "'"
2) Use command parameters:
sql = "SELECT * from Departments WHERE Customer = ?"
Dim cmd As New OleDbCommand(sql, oledbCnn)
cmd.Parameters.AddWithValue("#p1", cmbCustomer.Text)
If you are inserting dates this also has the advantage that you don't need to bother about date formats.
You can simplify your loop to:
While dr.Read()
cmbDept.Text = CStr(dr("Name"))
End While
There is no need to test for HasRows since dr.Read() would return False anyway if no rows were available.
You can have Dispose called automatically by VB with the Using statement:
Using cmd As New OleDbCommand(sql, oledbCnn)
'TODO: Work with cmd here.
End Using
Dispose will be called at the end of the Using block, even if an error occurs within the Using block or the Using block is left by Return or another statement.
You do not need to check if the data reader has rows every iteration, just check it before you loop.
You are not adding the items to the list, but rather setting the Text property of cmbDept, instead do this:
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'"
Dim cmd As New OleDb.OleDbCommand
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
If (dr.HasRows) Then
While dr.Read()
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End While
End If
cmd.Dispose()
dr.Close()
End Sub
Also, it is highly recommended that you use a parameterized query as to avoid a visit from Little Bobby Tables, like this:
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = #Customer"
Dim cmd As New OleDb.OleDbCommand
cmd.Parameters.AddWithValue("#Customer", cmbCustomer.Text)
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
If (dr.HasRows) Then
While dr.Read()
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End While
End If
cmd.Dispose()
dr.Close()
End Sub