How to populate a combobox in vb.net with filtered data from an msaccess table - vb.net-2010

I would really appreciate any help I can get.
My problem is that I have Combobox1 bound to a BindingSource and the DataMember and ValueMember property linked and working. For the life of me I do not know how to use the value (selected valuemember) of Combobox1 to filter the results I show on Combobox2. I am desperate for a simple way to do this.
my failing code is below
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim conn As New SqlConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Database1.mdb") 'This line fails
Dim strSQL As String = "SELECT * FROM Questions WHERE Section='" & ComboBox1.ValueMember & "'"
Dim da As New SqlDataAdapter(strSQL, conn)
Dim ds As New DataSet
da.Fill(ds, "Disk")
With ComboBox2 'Here i try to populate the combobox2
.DataSource = ds.Tables("Questions")
.DisplayMember = "Question_String"
.ValueMember = "Question_Code"
.SelectedIndex = 0
End With
End Sub
I keep getting a system level error as follows
{"Keyword not supported: 'provider'."}
I have tried a few other options but the errors I get seem more cryptic can someone please help me on this. I will appreciate it a lot.

Dim conn As New OleDBConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='|DataDirectory|\Database1.mdb'")
Also your query has to use a string not an object so try...
Dim strSQL As String = "SELECT * FROM Questions WHERE Section='" & ComboBox1.ValueMember.toString & "'"

Because you are using a Provider for a connection that doesn't need it because the provider should be an SQL driver.
I don't know what database you are using (well, the file is an access file), but you need to check you have the correct connection string
see http://www.connectionstrings.com/sql-server-2008#p2

Here are a couple of observations about your code that I hope you find helpful:
First, you might want to look at this MSDN help on how to move your database connection string out of the code and into a configuration file. This is especially important for your code to work to work more seemlessly across different environment (dev box, staging, production, etc) - Connection Strings and Configuration Files (ADO.NET)
I also noticed that you never explicitly open or close the connection. Per this entry on stack overflow, you should be ok, but keep in mind that if you happen to change the code to explicitly open the connection you will also need to close it.
I also noticed that you aren't using a parameterized query. This makes your code vulnerable to a SQL Injection attack. Here is a link to a blog posting by Scott Guthrie 'Tip/Trick: Guard Against SQL Injection Attacks'. You never know who may copy and paste your block of code with this bad practice.
Finally, you do the following query (with appropriate mods from other answers:
Dim strSQL As String = "SELECT * FROM Questions WHERE Section='" & ComboBox1.ValueMember.toString & "'"
And subsequently only use Question_String, and Question_Code in your code. You might want to consider changing your query to only pull the columns you need. This is especially helpful when you have tables with many columns. Otherwise you will needlessly pull data your code never actually needs. So your query would become:
Dim strSQL As String = "SELECT Question_String, Question_Code FROM Questions WHERE Section='" & ComboBox1.ValueMember.toString & "'"

Related

How do I fetch data from Access database records and display/save them as textboxes/variables in VB.net?

coding noob here. I'm looking for help after hours of googling and watching YouTube tutorials provided no success. I've also tried looking at many of the posts on this website. I keep running into the same problem.
In Visual Studio I am attempting to create a solution with VB.net, it is currently successfully linked to an Access Database with which I can view, add, edit, and save records live.
I am trying to fetch data from the Access database based on a search of one of the fields, and then save that data as a variable.
(Code shown below)
Upon attempting to click the search button, I received the following exception: System.Data.OleDb.OleDbException: 'Syntax error (missing operator) in query expression 'First Name'.'
I believe it is because my field names are two words, but I have no idea how to fix this. Just typing it with one word gives this exception instead:
System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.'
I have been completely unable to make progress despite watching multiple different versions of tutorials on how to perform this. Could someone please help me out?
Here is the code:
Public Class FormTraits
Private Sub FormTraits_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub FNButton_Click(sender As Object, e As EventArgs) Handles FNButton.Click
Dim conn As New OleDbConnection
conn.ConnectionString = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Access Database.accdb")
conn.Open()
Dim strsql As String
strsql = "select ID, First Name, Last Name from PlayerData where First Name=" + TextBoxSearch.Text + ""
Dim cmd As New OleDbCommand(strsql, conn)
Dim myreader As OleDbDataReader
myreader = cmd.ExecuteReader
myreader.Read()
TextBoxFirstName.Text = myreader("First Name")
TextBoxLastName.Text = myreader("Last Name")
TextBoxID.Text = myreader("ID")
conn.Close()
End Sub
End Class
You should avoid using names including spaces or other special characters for tables, columns, etc, in your database. Just as you would do for a variable name or the like in VB - and as you have done for your table name - you should name your columns FirstName and LastName. If you must include spaces or other special characters, you must escape the identifiers in your SQL code. You also need to wrap text literals in single quotes, much as you wrap them in double quotes in VB:
strsql = "SELECT ID, [First Name], [Last Name] FROM PlayerData WHERE [First Name] = '" & TextBoxSearch.Text & "'"
It would be better if you used parameters instead of string concatenation, but that's beyond the scope of this question.

Read Value from Database in TextBox when Combobox text changes VB.NET

I have a list of Users Names in ComboBox and Some TextBoxes. When ComboBox text changes (i.e I select some username from ComboBox), The TextBoxes are filled with user details from the database.
I have code to achieve this in SQL Database. But these queries are not working with MsAccess database.
MysqlConn = New MySqlConnection
Mysql.ConnectionString = "server=localhost;user=root;password=root;database=database"
Dim READER As MySqlDataReader
Try
MysqlConn.open()
Dim Query As String
Query("select * from database.usernames where name='" & ComboBox1.Text & "'")
Command = New MySqlCommand(Query, MysqlConn)
READER = Command.ExecuteReader
While READER.Read
TextBox1.Text = READER.GetString("name")
End While
End Try
Here is my answer. Please don't get overwhelmed by it. ;)
Broken code
First of all, as I see it, the code you provided cannot work at all, because:
your Query variable is initialized in an invalid (or at least a very exotic) way. You probably want to use something like:
Dim Query As String
Query = "select * from database.usernames where name='" & ComboBox1.Text & "'"
or in a single line:
Dim Query As String = "select * from database.usernames where name='" & ComboBox1.Text & "'"
you try to assign the connection string to the ConnectionString property of a nonexistent Mysql variable. Or the variable exists because it is declared somewhere else, which might be a bug in your code snippet here. But I assume you want to assign the connection string to the MysqlConn.ConnectionString property instead.
you have not declared the MysqlConn and Command variables anywhere. You only just assign to them. (I will simply assume you have declared the variables correctly somewhere else in your code...)
the IDataRecord interface does not provide a GetString(name As String) method overload. So unless you have defined a custom extension method for it, you probably need to use the IDataRecord.GetOrdinal(name As String) method as well, or use the column index instead of the column name.
Anyway, the code you provided uses MySQL. So I assume that MySQL is the "SQL Database" you are using successfully. And that seems to work, as you say? Well... Hmmm... Then I will simply assume your code snippet is completely correct and works perfectly with MySQL... :/
MS Access vs. MySQL
Using MS Access requires other data access classes (probably the ones in namespace System.Data.OleDb) and another connection string. You could take a look at this ADO.NET OleDb example for MS Access in the Microsoft documentation.
You probably even have to update your SQL query, because every database system uses its own SQL dialect. You might want to consult the Office documentation for that. But your query is quite simple, so perhaps all you have to do to make it work with MS Access is:
remove the database name and use only the table name, and
delimit the name identifier (since it is a reserved keyword in MS Access).
I personally delimit all identifiers in my SQL queries, just to avoid unintended conflicts with reserved keywords. So I would personally use something like this:
select * from [usernames] where [name] = '...'
Additional tips
Also, I would like to provide you some additional (unrelated) tips regarding improving your code:
Use Using-statements with variables of an IDisposable type as much as possible. Those types/classes do not implement that interface if there isn't a good reason for it, so I consider it not unimportant to call Dispose when you are done with such disposable objects (or using a Using statement to call Dispose implicitly).
Use SQL parameters (if possible) to avoid SQL injection vulnerabilities. Look at this StackOverflow question and its answer for an example of how to use SQL parameters with MS Access.
Example
You may take a look at the following code snippet. It might not provide a working example out-of-the-box, but you might get some useful/practical ideas from it:
Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Data\\database.mdb;User Id=admin;Password="
Dim query As String = "select * from [usernames] where [name] = #Name"
Using conn As New OleDbConnection(connectionString)
Using command As New OleDbCommand(query)
command.Parameters.Add("#Name", OleDbType.VarChar, 50).Value = ComboBox1.Text
conn.Open()
Using reader As OleDbDataReader = command.ExecuteReader
If reader.Read Then
textbox1.Text = reader.GetString(reader.GetOrdinal("name"))
End If
End Using
End Using
End Using

VB.net Getting Scalar to save a value to a variable

I've been looking through the forums with no luck. I am trying to retrieve a value from a database and store it to a variable. The closest I got was following This. Here is my Code:
Dim dblAircraftHourlyRate As Double
Dim intAircraftID As Integer
intAircraftID = ddAircraft.SelectedItem.Value
Dim mySqlComm As String = "SELECT HourlyRate FROM Aircraft WHERE AircraftID = '" & intAircraftID & "'"
Using cn As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Rollin Laptop\Desktop\CurrentAll2Fly3\App_Data\ASPNETDB.MDF;Integrated Security=True;User Instance=True"), _
cmd As New SqlCommand(mySqlComm, cn)
cn.Open()
dblAircraftHourlyRate = Convert.ToDouble(cmd.ExecuteScalar())
End Using
I'm not sure why, but instead of saving the HourlyRate to the dblAircraftHourlyRate, it is saving the intAircraftID to dblAircraftHourlyRate. I'm also not sure why the example code did not close the database connection. Any ideas on how to fix this to get the correct variable?
My solution had nothing to do with the question, but I had a separate bit of code that was executing after the bit I posted. It was resetting the value of dblAircraftHourlyRate such that dblAircraftHourlyRate = ddAircraft.SelectedItem.Value After I commented out the line, the code worked perfectly. To clarify, the value in the dropdownlist was the AircraftID, not the HourlyRate.
Tim Schmelter also helped me out in his explanation of how Connection-Pooling works:
Connection-Pooling is enabled by default. Default means that it's enabled even if you don't specify the Pooling parameter in your connection-string. Connection-pooling helps to improve performance since it maintains the state of the physical connections. So even if you close a connection the physical connection keeps open (If you check it in the database). You are using the Using-statement which is best practise. Disposing a connection will "close" it. – Tim Schmelter

Using TableAdapter to insert rows into a dataset does not do anything

I have a question similar to this one, but reading the (accepted) answer didn't give me much insight, so I'm hoping to state it more clearly and get a clearer response back.
I'm attempting to insert a data row into a table. I'm using TableAdapter's custom "insert nonQuery" that I wrote (it works, I tested) to accept some parameters. I'm fairly new to this business of communication with a database via .NET and what I'm doing is probably wrong by design. My questions are why is it wrong and what's the right way to do it? Both are equally important, IMO.
Here's some sample VB code I wrote:
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
Try
arraysTableAdapter.InsertArray("Test Array", 2, 1, 2, "Test user")
Catch ex As SqlException
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
...and that's pretty much it. There is no exception raised, my table does not get a new row inserted. Everything is just the way it was before I called the InsertArray method. When I test my query in the QueryBuilder with the same parameters, a new row gets added to the database.
Now, I do understand some of the reasons this would not work. I understand that I need to create and select a row in my DataSet (no idea how to do it) in order to tell the TableAdapter what it's adding the data to. Or at least I got that impression from reading the vast abyss of forums.
I would really like to use TableAdapter at some point, because it knows that .InsertArray exists and it knows which parameters it likes. I could try and do it using
Dim con As New SqlConnection
Dim cmd As New SqlCommand
con.ConnectionString = connString
con.Open()
cmd.CommandText = "INSERT ...... all that jazz"
but it's not nearly clean enough for how clean I like my code to be. So, is there any way to do what I'm trying to do the way I'm doing it? In other words, how do I use the neat structure of a TableAdapter to communicate to my DataSet and put a new row in it?
Thanks in advance!
There were two things that were wrong:
(minor issue) I did not have a DataTable filled from the TableAdapter (see code below)
(major, sneaky issue) My method worked from the very beginning. There is nothing extra to be added except for the line above. However, the ConnectionString of arraysTableAdapter was pointing my program (automatically, by default) to a wrong location. Once I manually set the ConnectionString, it worked perfectly.
Here's my complete code:
Dim connString As String = "Some correct connection string"
Dim arraysDataTable As New SpeakerTestsDataSet.ArraysDataTable
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
'Set the correct connection string'
arraysTableAdapter.Connection.ConnectionString = conn
'Fill table from the adapter'
arraysTableAdapter.Fill(arraysDataTable)
Try
arraysTableAdapter.Insert("Test", 2, 1, 2, Now, Now, "Me")
Catch ex As Exception
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
The accepted answer in the question you linked to is correct, but sometimes saying it in different words helps:
A TableAdapter is used to communicate between a DataTable (there can be one or more DataTables in a DataSet) and a database. It can pull data from a database and add it to a DataTable and it can send data from a DataTable to the database. It's purpose is to create and execute the SQL code required to make this communication work.
You are trying to use the TableAdapter to directly add data to your DataTable. This will not work. Instead, you should use the methods that come with the DataTable to add a new row to the DataTable and then (if necessary) use your TableAdapter to send that row to a database.
For instance, with a Dataset called DataSet1 that contains a DataTable called DataTable1 that has three text columns you can add a record like this:
Dim d As New DataSet1
d.DataTable1.AddDataTable1Row("value1", "value2", "value3")
That AddDataTable1Row method is automatically created for you, and I think is what you are looking for.

Recordsets in VB.NET

All,
Trying to implement a recordset approach in VB.NET and (with the wonderful help of this community) have gotten to the point where things almost run. :)
Code:
Dim strSQL As String
Dim rsMaster As New ADODB.Recordset
strSQL = "select * " & "from tblDQ " & "order by xid, xcode, xDOS"
rsMaster.Open(strSQL, objConn, adOpenForwardOnly, adLockOptimistic)
The last line throws an exception while attempting to execute the rsMaster.Open line:
COM Exception was unhandled
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
Any ideas? Changing the cursor type or lock type doesn't seem to do any good, and the types specified above are available as options when coding the line. I've (on a WAG) added the following lines to the project:
Imports ADODB.LockTypeEnum
Imports ADODB.CursorTypeEnum
with no luck.
TIA!
Dave
Some ideas:
Does the SQL statement work in a "pure" database tool? (The &s looks a bit strange, but I assume that's a formatting issue in SO.)
The select * should work, but try a specific simple column (a short string or an integer), maybe there is an issue with a "tricky" column data type.
Do you have the objConn declared and a proper connection opened?
Some more ideas:
As you get the error when you execute the statement it seems that there is a problem with your statement. Is there a really simple SQL statement that will work in your scenario? (no order by, just a column, ..)
Try the statement from within MSAccess using the same connection parameters you are using in your VB.NET program. Maybe you are using a different user from within your program, maybe you have to qualify the table name etc.
If you say the connection is working fine, what did you do using the connection? Was there anything requiring access to the DB?
Ok, if removing the adOpenForwardOnly and the adLockOptimistic parameters doesn't change anything, how about changing the code slightly to use the Execute Method of the Connection object?
rsMaster.Open(strSQL, objConn, adOpenForwardOnly, adLockOptimistic)
Becomes
rsMaster = objConn.Execute(strSQL)
Not sure about your connection. You have an Access tag, but mentioned you tested in SQL Server. If you are using an access .mdb file
Imports adodb
Public Class Form1
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim strSQL, strConn As String
Dim rsMaster As New ADODB.Recordset
Dim objConn As New ADODB.Connection
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DQ\DQ.mdb"
objConn.Open(strConn)
strSQL = "select * " & "from tblDQ " & "order by xid, xcode, xDOS"
rsMaster.Open(strSQL, objConn, CursorTypeEnum.adOpenForwardOnly, LockTypeEnum.adLockOptimistic)
rsMaster.MoveFirst()
Me.Text = rsMaster("xcode").Value
rsMaster.Close()
rsMaster = Nothing
End Sub
End Class