VB.net Query wont retrieve data from access database - vb.net

I have created a query using vb.net with parameters which should allow the query to retrieve data from my access database but however when I click on the button it only shows blank fields but no rows are retrieved from the database. Could you please help me what I am currently doing wrong.
Imports System.Data.OleDb
Public Class RouteToCruise
Private Sub RouteToCruise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Route_Btn_Click(sender As Object, e As EventArgs) Handles Route_Btn.Click
Try
Dim row As String
Dim connectString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\DeepBlueTables.mdb"
Dim cn As OleDbConnection = New OleDbConnection(connectString)
cn.Open()
Dim CruiseQuery As String = "SELECT Route.RouteName + ', ' + Cruise.CruiseID As CruiseRoute FROM Route INNER JOIN Cruise ON Route.RouteID = Cruise.RouteID WHERE CruiseID = ?"
Dim cmd As New OleDbCommand(CruiseQuery, cn)
'cmd.Parameters.AddWithValue("CruiseID", OleDbType.Numeric).Value = Route_Txt.Text
cmd.Parameters.AddWithValue(("CruiseID"), OleDbType.Numeric)
Dim reader As OleDbDataReader = cmd.ExecuteReader
'RCTable.Width = Unit.Percentage(90.0)
RCTable.ColumnCount = 2
RCTable.Rows.Add()
RCTable.Columns(0).Name = "CruiseID"
RCTable.Columns(1).Name = "RouteName"
While reader.Read
Dim rID As String = reader("RouteID").ToString()
cmd.Parameters.AddWithValue("?", rID)
row = reader("CruiseID") & "," & ("RouteName")
RCTable.Rows.Add(row)
End While
reader.Close()
cn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
If the user enters route name in the text box then the rows should show cruise ID and route name for each of the selected routes. for example if users enters Asia in the text box, clicks on the button then the query should return the cruiseID for the cruises which are going to Asia.

Your use of parameters makes no sense. First you call AddWithValue and provide no value, then you execute the query and then you start adding more parameters as you read the data. Either you call AddWithValue and provide a value, or you call Add and then set the Value on the parameter object created. Either way, it MUST be before you execute the query or it's useless.
myCommand.Parameters.AddWithValue("#ParameterName", parameterValue)
or
Dim myParameter = myCommand.Parameters.Add("#ParameterName", OleDbType.Numeric)
myParameter.Value = parameterValue

Related

Database query not returning results from value

I am making a work management system and I am fairly new to Visual Basic.
What I am trying to do is retrieve the name of the employee from the database with the given ID. After that I want this name to be displayed in a Label. After that, he can press the Work Start or Work end buttons.
Here is the code:
Private Function employeeSearchwithID(PersonalNr As String) As String
Dim mitarbeiter As String
Dim r As DataRow
Access.ExecQuery("SELECT [Vorname], [Name] from [TA-Personal] WHERE ([Personal_Nr] = '" & PersonalNr & "');")
'Report and Abort on Erros or no Records found
If NoErros(True) = False Or Access.RecordCount < 1 Then Exit Function
r = Access.DBDT.Rows(0)
'Populate Label with Data
mitarbeiter = r.Item("Vorname") & " " & r.Item("Name")
Return mitarbeiter
End Function
It is used like this:
Private Sub tbxUserInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbxUserInput.KeyDown
If e.KeyCode = Keys.Enter Then 'employeeIDnumbersSelect()
Label5.Text = employeeSearchwithID(tbxUserInput.ToString)
End If
End Sub
So, the plan is to have this program running on a tablet connected to a scanner. Every employee will have a personal card. When they scan the card, I want their names to be displayed. Of course, the card will be with the ID. But I am having trouble with the names: when I give my personal number it comes up as an empty string.
I have a separate DB Module. I learned from a tutorial:
Imports System.Data.OleDb
Public Class DBControl
' DB Connection
Public DBCon As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\recycle2000.mdb;")
'DB Command
Public DBCmd As OleDbCommand
'DB Data
Public DBDA As OleDbDataAdapter
Public DBDT As DataTable
'Public Myreader As OleDbDataReader = DBCmd.ExecuteReader
'Query Paramaters
Public Params As New List(Of OleDbParameter)
' Query Stats
Public RecordCount As Integer
Public Exception As String
Public Sub ExecQuery(Query As String)
'Reset Query Stats
RecordCount = 0
Exception = ""
Try
'Open a connection
DBCon.Open()
'Create DB Command
DBCmd = New OleDbCommand(Query, DBCon)
' Load params into DB Command
Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))
' Clear params list
Params.Clear()
' Execute command & fill Datatable
DBDT = New DataTable
DBDA = New OleDbDataAdapter(DBCmd)
RecordCount = DBDA.Fill(DBDT)
Catch ex As Exception
Exception = ex.Message
End Try
' Close your connection
If DBCon.State = ConnectionState.Open Then DBCon.Close()
End Sub
' Include query & command params
Public Sub AddParam(Name As String, Value As Object)
Dim NewParam As New OleDbParameter(Name, Value)
Params.Add(NewParam)
End Sub
End Class
Without knowledge of the Access class, I have to recommend a different approach to querying the database. It is important to make sure that the database is not vulnerable to SQL injection, be it deliberate or accidental. The way to do that is to use what are known as SQL parameters: instead of putting the value in the query string, the value is supplied separately.
Private Function EmployeeSearchwithID(personalNr As String) As String
Dim mitarbeiter As String = String.Empty
Dim sql = "SELECT [Vorname], [Name] from [TA-Personal] WHERE [Personal_Nr] = ?;"
Using conn As New OleDbConnection("your connection string"),
cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add(New OleDbParameter With {.ParameterName = "#PersonalNr",
.OleDbType = OleDbType.VarChar,
.Size = 12,
.Value = personalNr})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.Read() Then
mitarbeiter = rdr.GetString(0) & " " & rdr.GetString(1)
End If
End Using
Return mitarbeiter
End Function
Private Sub tbxUserInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbxUserInput.KeyDown
If e.KeyCode = Keys.Enter Then 'employeeIDnumbersSelect()
Dim employeeName = EmployeeSearchwithID(tbxUserInput.Text.Trim())
If String.IsNullOrEmpty(employeeName) Then
MessageBox.Show("Not found.", "Problem", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Else
Label5.Text = employeeName
End If
End If
End Sub
The Using command makes sure that the "unmanaged resources" involved in querying a database are cleaned up afterwards, even if something goes wrong.
You will need to change the value of OleDbType.VarChar and .Size = 12 to match the type and size of that column in the database.
The name of the parameter is only for convenience with OleDb because it is ignored in the actual query, which uses "?" as a placeholder. Please see OleDbCommand.Parameters Property for full information.
If it still does not work, then please enter the ID manually in the tbxUserInput and see if you can make it work that way.
Hang on... tbxUserInput.ToString should be tbxUserInput.Text. But everything else I wrote still applies.

Compare db value with textbox value VB

My Table
I load the windows user name to textbox1.text using 'System.Environment'
After that I query this and compare the textbox value to the PersonName in db
if it matches, I want to get the relevant Department name ie if it's 'manager'
then I want to display a form from menuitem_click event. My code is below
it dosent work can some one please help with this.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Dim cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Dim cmd As New SqlClient.SqlCommand
Dim tbl As New DataTable
Dim da As New SqlClient.SqlDataAdapter
Dim reader As SqlClient.SqlDataReader
Dim ta As String
Try
cn.Open()
Dim sql As String
sql = "select * from dbo.Person where [PersonName] ='" + TextBox1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
While reader.Read
ta = reader.Item("Department")
If ta = 'Maneger' Then
Form2.Show()
End If
' TextBox2.Text = reader.Item("Department")
'TextBox2.Text = reader.Item("dob")
End While
cn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
No matter how you spell it, Manager or Maneger, just make sure what is in the database matches what is in your If statement. I think I would use a drop down box for you to select the Department wherever you are inserting the Person so the Department name would match.
The Using...End Using blocks ensure that you database objects are closed and disposed even if there is an error.
You can pass your Sql statement and the connection directly to the constructor of the command. If all you need is the Department then don't drag down all the date with "*".
Never concatenate strings to build Sql statements. A hacker could type in TextBox1 "Joe; Drop Table dbo.Person;" Using parameters stops this hole because the .Value of the parameter is treated as only a value not executable code.
You are only expecting one value in return so you can use .ExecuteScalar which returns the first column of the first row in the result set.
Your code is very fragile because I suspect you could have duplicate names unless you require unique user names.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Try
Using cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Using cmd As New SqlClient.SqlCommand("Select Department From dbo.Person Where PersonName = #Name;", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text
cn.Open()
Dim ta As String = cmd.ExecuteScalar.ToString
If ta = "Maneger" Then
Form2.Show()
End If
TextBox2.Text = ta
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Take combobox SelectedIndex data and use in SELECT Query - VB.net

I'm a little desperate, hence why I'm here! I'm quite new to programming and have been given an assignment where I need to use a range of SQL queries to generate a simple HTML report table. There is also a user input, with them selecting the ClinicID from the comboBox and clicking a button to generate the report.
Basically, I have a comboBox that I have populated with 'ClinicID', as below. I have also made sure that SelectedIndex is working. I need to somehow use this in the SQL query method which I have also provided below.
Public Class frmReport1
'Set lsData for Clinics table
Dim lsData As List(Of Hashtable)
'On form load
Private Sub frmReport1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cboClinicID.DropDownStyle = ComboBoxStyle.DropDownList
'Instantiate new ClinicController object
Dim cController As ClinicController = New ClinicController
'Load ClinicID
lsData = cController.findId()
For Each clinic In lsData
cboClinicID.Items.Add(CStr(clinic("ClinicID")))
Next
End Sub
'Selected Index
Private Sub cboClinicID_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboClinicID.SelectedIndexChanged
Dim selectedIndex As Integer = cboClinicID.SelectedIndex
Dim selectedItem As Object = cboClinicID.SelectedItem
'Print in debug window
Debug.Print("Selected clinicID: " & selectedItem.ToString())
Debug.Print("Selected clinicID index: " & selectedIndex.ToString())
Dim htData = lsData.Item(selectedIndex)
End Sub
SQL query method - **note, I'm pulling from two different tables:
Where the '?' is, is where I assume I have to work in the 'SelectedItem' but I have no idea how!
Desired result: an html table outputted with these three selected fields.
Public Class ClinicOrderController
Public Const CONNECTION_STRING As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=PharmDB.accdb"
'Dim cController As ClinicController = New ClinicController
'Dim oController As OrderController = New OrderController
Public Function findClinicOrder() As List(Of Hashtable)
'Instantiates a connection object
Dim oConnection As OleDbConnection = New OleDbConnection(CONNECTION_STRING)
'Instantiates a list of hashtables
Dim lsData As New List(Of Hashtable)
Try
Debug.Print("Connection string: " & oConnection.ConnectionString)
oConnection.Open()
Dim oCommand As OleDbCommand = New OleDbCommand
oCommand.Connection = oConnection
'Stored in the CommandText property of the command object
'SELECT SQL statement
oCommand.CommandText = "SELECT clinics.clinic_id, orders.date_ordered, orders.total_price FROM clinics, orders WHERE clinics.clinic_id = orders.clinic_id AND clinics.clinic_id = ? ORDER BY clinics.clinic_id"
'Compiles the prepared statement
'oCommand.Prepare()
'Executes the SQL statement and stores the results in data reader object
Dim oDataReader = oCommand.ExecuteReader()
'Process data set in Hashtable
Dim htTempData As Hashtable
Do While oDataReader.Read() = True
htTempData = New Hashtable
htTempData("ClinicID") = CStr(oDataReader("clinic_id"))
htTempData("DateOrdered") = CStr(oDataReader("date_ordered"))
htTempData("OrderTotalPrice") = CStr(oDataReader("total_price"))
lsData.Add(htTempData)
Loop
Debug.Print("The record was found.")
Catch ex As Exception
Debug.Print("ERROR:" & ex.Message)
MsgBox("An error occured!")
Finally
oConnection.Close()
End Try
'Return list of hashtables to the calling function
Return lsData
End Function
Really, really appreciate any help here. Ive been struggling with this for more than 8 hours (not joking - I give you permission to laugh)
If i understand you correctly, you want to use your dropdown selected item in your WHERE clause. To achieve that , revise your joining using INNER JOIN with ON then place your filtering in WHERE condition. Hope code below will help.
SELECT clinics.clinic_id,
, orders.date_ordered
, orders.total_price
FROM clinics INNER JOIN orders ON clinics.clinic_id = orders.clinic_id
WHERE clinics.clinic_id = selectedItem.ToString()
ORDER BY clinics.clinic_id
if the selectedItem.ToString() did not work, you can try SelectedValue
Assuming that clinic_id is a numeric field in the database: (otherwise just surround it with single quotes (''))
string clinicID = cboClinicID.SelectedItem.ToString();
string sql = string.Format(#"SELECT clinics.clinic_id, orders.date_ordered, orders.total_price
FROM clinics, orders
WHERE clinics.clinic_id = orders.clinic_id
AND clinics.clinic_id = {0}
ORDER BY clinics.clinic_id", clinicID);
oCommand.CommandText = sql;
You can also do it like this:
string sql = "SELECT clinics.clinic_id, orders.date_ordered, orders.total_price " +
"FROM clinics, orders " +
"WHERE clinics.clinic_id = orders.clinic_id " +
"AND clinics.clinic_id = " + clinicID + " " +
"ORDER BY clinics.clinic_id";
Please provide code in vb.net
Here is my code, I want to display prize amount from table where class id is condition :
If class id is 3 then prize for that is display in my textbox named txtprize.text and class Id is displayed in list box.
Private Sub listClassID_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listClassID.SelectedIndexChanged
Dim classIdlist As String
classIdlist = New String(listClassID.SelectedItem.ToString)
Dim strSQL As String = "select [Prize Amount] from Master_Class WHERE [Class ID] =" & classIdlist
Dim dr As SqlDataReader
Try
con.Open()
cmd = New SqlCommand(strSQL, con)
dr = cmd.ExecuteReader()
If dr.Item(0) Then
txtPrize.Text = dr("[Prize Amount]").ToString
End If
dr.Close()
cmd.Dispose()
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub

Database not updating new row

Insert new row inside DataGridView
This answer makes it seem like the database should update with the rows.add
Some other sites have instructions, but form a perspective of creating the database from scratch. I already have a database and just want the stupid thing to accept new data.
Here's what I have done:
Private Sub InitializeDataGridView()
Try
' Set up the DataGridView.
With Me.DataGridView1
' Automatically generate the DataGridView columns.
.AutoGenerateColumns = True
' Set up the data source.
'bindingSource1.DataSource = GetData("SELECT * FROM Places and Stuff")
MyTable = GetData("SELECT * FROM Places and Stuff")
'MyDataSet = bindingSource1.DataSource
'MyTable = MyDataSet.Tables(0)
.DataSource = MyTable
' Automatically resize the visible rows.
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
' Set the DataGridView control's border.
.BorderStyle = BorderStyle.Fixed3D
' Put the cells in edit mode when user enters them.
.EditMode = DataGridViewEditMode.EditOnEnter
' Disables Add New Row
.AllowUserToAddRows = False
End With
Catch ex As SqlException
MessageBox.Show(ex.ToString, _
"ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
System.Threading.Thread.CurrentThread.Abort()
End Try
End Sub
I am binding the DGV to a table. It seems like maybe I need a dataset somewhere to update but I cannot figure out how to populate a dataset with a table that is also a sql database. You can also see where I have played around with other datasets/datatables etc.
I also got my datagridview to add a row but the database is being lazy:
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
'Determine Last Row Index
Dim dgvrowCnt As Integer = DataGridView1.Rows.Count - 1
If DataGridView1.Rows.Count > 0 Then
Dim myRow As DataRow = MyTable.NewRow
myRow(0) = DataGridView1.Rows(dgvrowCnt).Cells(0).Value + 1
MyTable.Rows.Add(myRow)
Else
Dim myRow As DataRow = MyTable.NewRow
myRow(0) = 230
MyTable.Rows.Add(myRow)
End If
End Sub
I am a little saddened by not being able to use myRow("<column name here>") = 230 but I'll have to get over it I guess.
I have tried refreshing and checking the table to see if my form needs to be refreshed, but that doesn't seem to be the case.
This page http://support.microsoft.com/kb/301248 has 2 lines and claims it does what I am hoping for:
Dim objCommandBuilder As New SwlCammandBuilder(daAuthors)
daAuthors.Update(dsPubs, "Authors")
I cannot get my table into a dataset as shown in the binding lines of my example.
It seems that you haven't understood a fundamental concept of ADO.NET. The DataTable and other objects like the DataSet are 'disconnected' objects, meaning that adding/updating and removing rows doesn't update/insert/delete the database table.
You need to create an SqlCommand, prepare its command text and then Execute a query to update your db (other methods include using an SqlDataAdapter and its Update method)
For example, to insert a single row in a datatable your code should be something like this
Using con = New SqlConnection(.....constringhere...)
Using cmd = new SqlCommand("INSERT INTO table1 (field1) values (#valueForField)", con)
con.Open()
cmd.Parameters.AddWithValue("#valueForField", newValue)
cmd.ExecuteNonQuery()
End Using
End Using
A more complete tutorial could be found here
Instead this could be a pseudocode to use a SqlDataAdapter and a SqlCommandBuilder to automate the construction of the commands required to store your changes back to the database
' Keep the dataset and the adapter at the global class level'
Dim da As SqlDataAdapter = Nothing
Dim ds As DataSet
Private Function GetData(ByVal sqlCommand As String) As DataSet
ds As New DataSet()
Dim connectionString As String = "Data Source=...."
Using con = New SqlConnection(connectionString)
conn.Open()
Using command = New SqlCommand(sqlCommand, con)
Using da = New SqlDataAdapter(command)
da.Fill(ds)
End Using
End Using
End Using
Return ds
End Function
Use the first table inside the DataSet returned by GetData as Datasource of the grid (or just use the whole dataset)
.DataSource = GetData(.......).Tables(0)
' Add a new button to submit changes back to the database'
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Dim builder = New SqlCommandBuilder(da)
da.UpdateCommand = builder.GetUpdateCommand()
da.InsertCommand = builder.GetInsertCommand()
da.DeleteCommand = builder.GetDeleteCommand()
da.Update(ds)
End Sub
Please, note that I cannot test this code, and I offer it as a pseudocode without any error checking required by a more robust application.

How can I change the value of an item in a list box while keeping the items display the same?

I have a ListBox that gets populated with a SqlDataReader object and it looks great but the problem I'm running into is I want the data text field to display the data from the date field of the SQL query and have the data value of the ListBox to be from the url field. This is very easy to do if you use the Query Builder function within Visual Studio 2010. You just click on the ListBox and change the properties in the right hand properties column. However, since I didn't use the query builder function and I am coding it by hand, I cannot figure out for the life of me how to change the data text field of the list box to the date field and the data value field to the url field.
The logic behind this is that the user will be able to click on the date of their item, click the button, and it will navigate to the url that is provided in the SQL Database.
Here is the code I am using in the button click action;
Protected Sub SearchButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SearchButton.Click
Dim startDate As Date
Dim endDate As Date
Dim connectionString As String
startDate = TextStartDate.Text
endDate = TextEndDate.Text
connectionString = SqlDataSource1.ConnectionString.ToString
Dim sqlConnection1 As New SqlConnection(connectionString)
Using sqlConnection1
Dim command As SqlCommand = New SqlCommand( _
"SELECT first_name, last_name, date, url FROM tbl_paystubs WHERE date>='" + startDate.ToString + "' AND date<='" + endDate.ToString + "';", _
sqlConnection1)
sqlConnection1.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
While reader.Read
SearchListBox.Items.Add(reader.Item("url"))
End While
reader.Close()
End Using
sqlConnection1.Close()
End Sub
Here are some pictures to help illustrate as well.
EDIT: I think I made this question a little hard to understand so I am going to clarify a little. Inside of the ListBox, the items that are there are now showing the Date when the search is completed, my question is, how can I make the "Open" button open a browser window with the ListBoxItems corresponding URL field?
you could create a little class like this:
internal class LbItem
{
internal string url;
internal string data;
public override string ToString()
{
return this.data;
}
}
and add instances of this class to your ListBox.Items:
listBox1.Items.Add(new LbItem { url = "http:xyz", data = "123" });
the listbox will show the LbItems as returned by the overridden ToString() function ...
I changed the code to the following which answered my question!
Protected Sub SearchButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SearchButton.Click
Dim startDate As Date
Dim endDate As Date
startDate = TextStartDate.Text
endDate = TextEndDate.Text
Dim connectionString As String
startDate = TextStartDate.Text
endDate = TextEndDate.Text
connectionString = SearchDataSource.ConnectionString.ToString
Dim sqlConnection1 As New SqlConnection(connectionString)
Using sqlConnection1
Dim command As SqlCommand = New SqlCommand( _
"SELECT first_name, last_name, date, url FROM tbl_paystubs WHERE date>='" + startDate.ToString + "' AND date<='" + endDate.ToString + "';", _
sqlConnection1)
sqlConnection1.Open()
Dim da As New SqlDataAdapter(command)
Dim ds As New DataSet()
da.Fill(ds)
sqlConnection1.Close()
SearchListBox.DataSource = ds
SearchListBox.DataTextField = "date"
SearchListBox.DataValueField = "url"
SearchListBox.DataBind()
End Using
TextStartDate.Text = ""
TextEndDate.Text = ""
End Sub