Why combo box is not loaded from join sql query - vb.net

Dim cmd As New SqlCommand("SELECT MainDepartmentsTable.ID, FeesTable.ID,FeesTable.Particular,FeesTable.Fee from MainDepartmentsTable inner join SubDepartmentsTable on MainDepartmentsTable.ID = SubDepartmentsTable.MainDeptID inner join FeesTable on SubDepartmentsTable.MainDeptID = FeesTable.SubDepartmentID WHERE FeesTable.ID = '" & TextDepartmentID.Text & "' ", con)
Dim DataAdopter = New SqlDataAdapter(cmd)
Dim dt As New DataTable
DataAdopter.Fill(dt)
Load_Deparments()

First you need to validate the user input.
Using blocks ensure that you connection and command are closed and disposed.
Parameters save your database from sql injection. I had to guess at the datatype.
Private ConStr As String = "Your connection string"
Private Sub OPCode()
Dim DeptID As Integer
If Not Integer.TryParse(TextDepartmentID.Text, DeptID) Then
MessageBox.Show("Please enter a valid department ID.")
Exit Sub
End If
Dim dt As New DataTable
Using con As New SqlConnection(ConStr),
cmd As New SqlCommand("SELECT MainDepartmentsTable.ID,
FeesTable.ID,
FeesTable.Particular,
FeesTable.Fee
from MainDepartmentsTable
inner join SubDepartmentsTable on
MainDepartmentsTable.ID = SubDepartmentsTable.MainDeptID
inner join FeesTable on
SubDepartmentsTable.MainDeptID = FeesTable.SubDepartmentID
WHERE FeesTable.ID = #DepartmentID;", con)
cmd.Parameters.Add("#DepartmentID", SqlDbType.Int).Value = DeptID
con.Open()
dt.Load(cmd.ExecuteReader)
End Using
Load_Departments(dt)
End Sub
Private Sub Load_Departments(dt As DataTable)
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "Particular"
ComboBox1.ValueMember = "Fee"
End Sub

Let's simplify a bit:
Dim sql = "SELECT FeesTable.ID, CoNCAT(FeesTable.Particular, '-', FeesTable.Fee) as DisplayText
FROM
SubDepartmentsTable
inner join FeesTable on SubDepartmentsTable.MainDeptID = FeesTable.SubDepartmentID
WHERE SubDepartmentsTable.MainDeptID = #id"
Dim da As New SqlDataAdapter(sql, con)
da.SelectCommand.Parameters.AddWithValue("#id", Convert.ToInt32(TextDepartmentID.Text)) 'less worried about AWV with ints but read https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
Dim dt As New DataTable
da.Fill(dt)
'this part connects the data to the combo - it's the part you didn't show in your Q and what people are telling you is missing
yourCombo.DisplayMember = "DisplayText"
yourCombo.ValueMember = "ID"
yourCombo.DataSource = dt
This isn't intended to be a paste in fix for your problem; you've left out too much info from your question to know how to answer it exactly, so you're gonna have to modify this
Things you need to change:
The columns that are selected in the SQL - load one column you will show (I demonstrated how to combine two bits of info under one name of DisplayText) and one column for the backing value (ID)
The column that is filtered on in the where clause or the name of the text box TextDepartmentID - it seems odd to me that a Fee ID should be equal to a Department ID, so I've altered the SQL to retrieve the Fee details for a MainDepartmentID because I've assumed your textbox name is correct and that you intended to show the fees for a department via the subdepartments
Read the blog linked and perhaps choose adding a parameter in a different way
Change yourCombo to the name of your combobox
Change DisplayMember and ValueMember setting to match the names of the two columns your SQL query selects
You only need two columns if youre plumbing up a combo, but if you pass the datatable off somewhere you can add more

Related

How i can get max value with a condition in within datatable VB.NT

I have datatable named (Dt)
Has 2 column ("Type","value").
How i can get max value where tybe = textbox1.text ____
in (datatable)ADO.net not SQL server
Thank you
Ok, so lets assume two buttons.
First button to load the data table form SQL server
(that you suggest/note you already have the data table).
next, we have a text box for user to enter the column name.
And then a button get max, which will use the text box with column name.
After that, we have a text box to show the results.
So, we have this code:
Dim rstData As New DataTable
Private Sub cmdLoadData_Click(sender As Object, e As EventArgs) Handles cmdLoadData.Click
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT * FROM tblhotelsA ORDER BY HotelName"
Using cmdSQL = New SqlCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
MsgBox("Data loaded", MsgBoxStyle.Information)
End Using
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If rstData.Rows.Count > 0 Then
' find max colum based on colum name in
Dim MyResult As Object
MyResult = rstData.Compute($"MAX({txtColumn.Text})", "")
Debug.Print(MyResult.ToString())
txtMax.Text = $"Max value for colum {txtColumn.Text} = {MyResult.ToString()}
-- colum data type = {MyResult.GetType.ToString()}"
End If
End Sub
and the results are now this:
Edit: User wants to build a sql query to get the max value
Ok, so the question is NOT that we have a data table (dt) in code, and we wish to pull/get/find the max value from that vb.net dt.
our question is that we want to query the database for a given column, and PUT THE RESULTS into that vb.net data table.
So, we want to QUERY SQL server to get the one result.
So, a very different goal.
This would be a "more common" question, and thus amounts to a plain jane SQL query.
this also of course will perform MUCH faster, since we don't pull nor have that vb.net "dt" or datatable, but we are to put the results of the sql query into that dt.
So, our form can look the same, but now our code for the "Get max" button would be this:
We do NOT require the first button to "load data" anymore.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
$"SELECT MAX(#P1) FROM tblhotelsA"
Using cmdSQL = New SqlCommand(strSQL, conn)
conn.Open()
cmdSQL.Parameters.Add("#P1", SqlDbType.NVarChar).Value = txtColumn.Text
rstData.Load(cmdSQL.ExecuteReader)
txtMax.Text = $"Max value for colum {txtColumn.Text} = {rstData.Rows(0)(0).ToString()}"
End Using
End Using
Now, say we want to "ask" the user for a given city, and then return the max found age for that user supplied city.
Then this:
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
$"SELECT MAX(Age) FROM tblhotelsA WHERE City = #City"
Using cmdSQL = New SqlCommand(strSQL, conn)
conn.Open()
cmdSQL.Parameters.Add("#City", SqlDbType.NVarChar).Value = txtWhatCity.Text
rstData.Load(cmdSQL.ExecuteReader)
txtMax.Text = $"Max age found for city = {txtcity.Text} = {rstData.Rows(0)(0).ToString()}"
End Using
End Using

How to populate a combobox from two different SQL Server database tables

I am trying to create a system that will load items from a database. There are two comboboxes; combobox1 which loads items from database table 1 and combox2 which loads items from database table 2.
Both tables are in the same database.
Here is was I tried but when I run the system I get this error:
(Conversion from string "SELECT * FROM dbo.Dishes" to type 'Long' is not valid.)
Here is the code I'm using:
Dim connection As New SqlConnection("Server = DESKTOP-1373H91; Initial Catalog = MealPreOrderSystem; Integrated Security = True")
connection.Open()
Dim query As String = "SELECT * FROM dbo.Dishes" And "SELECT * FROM dbo.Desserts"
Dim cmd As SqlCommand
cmd = New SqlCommand(query, connection)
Dim reader As SqlDataReader
reader = cmd.ExecuteReader
While reader.Read
cbxType.Items.Add(reader.Item("MealName"))
cbxType.Items.Add(reader.Item("DessertName"))
End While
connection.Close()
In VB.NET,AND is an operator.It is used to perform conjunction between either Booleans or Integers/Doubles/any numeric expression.Lets take your query string as an example :
Dim query As String = "SELECT * FROM dbo.Dishes" And "SELECT * FROM dbo.Desserts"
You are using AND here to join 2 sentences/strings which wouldn't result in anything rather it is trying to cast it as a Long.
Try to execute this command in SQL and you won't find any luck :(.
Your statements are correct :
SELECT * FROM dbo.Dishes
SELECT * FROM dbo.Desserts
But the way you are trying to achieve your goals is incorrect :(.
To get the data from the database into your combobox, what you can do is either use two comboboxes with separated SQL Queries/SQL Commands or you can use one combobox where you add data from both the databases but separate them with some special characters such as a comma ,
A sample may look like :
With one combobox
Dim cmd1 as new SqlCommand("SELECT * FROM dbo.Dishes",connection)
Dim dr as SqlDatareader = cmd1.ExecuteReader
While dr.Read
mycombo1.Items.Add(dr(0)) ' Here 0 is the column count,change it as required
End while
Dim cmd2 as new SqlCommand("SELECT * FROM dbo.Desserts",connection)
Dim dr2 as SqlDatareader = cmd2.ExecuteReader
While dr2.Read
mycombo2.Items.Add(dr2(0)) ' Here 0 is the column count,change it as required
End while
With 1 combobox
Here it gets a bit complicated.Firstly you need to populate your combobox from the data received from the first dataReader.Then, when the 2nd datareader is reading the data , you need to update the existing data/Item of the combobox keeping the existing data/item but adding new data/item to each existing data/item(separating them with ,).
Sample :
Dim i as Integer
Dim cmd1 as new SqlCommand("SELECT * FROM dbo.Dishes",connection)
Dim dr as SqlDatareader = cmd1.ExecuteReader
While dr.Read
mycombo1.Items.Add(dr(0))
End while
Dim cmd2 as new SqlCommand("SELECT * FROM dbo.Desserts",connection)
Dim dr2 as SqlDatareader = cmd2.ExecuteReader
While dr2.Read
mycombo1.Items(i) = myconbo1.Items(i) & "," & dr2(0)
i = i + 1
End while
Now, NOTE THAT I AM USING MULTIPLE DATAREADERS WITH THE SAME CONNECTION ,SO YOU MAY NEED TO INCLUDE MultipleActiveResultSets=True IN YOUR CONNECTION STRING or ENCLOSE THE DATAREADERS IN USING STATEMENTS or CALL dataReader.Close AFTER EACH DATAREADER HAS COMPLETED READING FROM THE DATABASE
This will solve your issue :)
Looks like you don't know how to write SQL queries (and your VB syntax itself looks faulty - string AND string?).
Dim connection As New SqlConnection("Server = DESKTOP-1373H91; Initial Catalog = MealPreOrderSystem; Integrated Security = True")
Dim query As String = <cmdString>
SELECT MealName as Name FROM dbo.Dishes
union
SELECT DessertName as Name FROM dbo.Desserts
</cmdString>
Dim cmd As SqlCommand
Dim reader As SqlDataReader
connection.Open()
cmd = New SqlCommand(query, connection)
reader = cmd.ExecuteReader
While reader.Read
cbxType.Items.Add(reader.Item("Name"))
End While
connection.Close()
Note: You are saying 2 comboboxes but your code seemed to be loading all the items to a single combobox. If you really need 2 comboboxes then use 2 SqlCommand and Reader loops (actually it would be better if you simply have used Linq for this).
You should be a bit more specific on what columns you are pulling from the 2 tables. if they are similar, you could write a sql query to UNION ALL the fields with a simple control to identify which record came from which table.
Example of SQL command string:
"SELECT 'M' AS Ctl, MealName AS aName FROM dbo.Dishes " &
"UNION ALL " &
"SELECT 'D' AS Ctl, DessertName AS aName FROM dbo.Desserts"
As mentioned by many here already, it seems like you are referencing only 1 ControlBox to list the fields returned cbxType
below is the reader (adapted to 2 ComboBoxes):
While reader.Read
Select Case reader.Item("Ctl")
Case "M"
cbxMType.Items.Add(reader.Item("aName"))
Case "D"
cbxDType.Items.Add(reader.Item("aName"))
End Select
End While
Hope this helps

Select from multiple tables without getting Parameter error

I am currently trying to code a database project for a musicians record log. I have been struggling to join 3 tables together in a single search of the database and I am getting this error:
No value given for one or more required parameters.
I have been searching online for why this is but cannot find anything which quite fixes my code. I have tried copying almost word for word other syntax but still get this error. Any help would be much appreciated, my database is as follows:
Program(ProgramID(PK), LengthOfProgram, UserName, NameOfProgram)
ProgramList(PieceListID(PK), PieceID(FK), ProgramID(FK))
Repertoire(PieceID(PK), NameOfPiece, Composer)
Those are the fields needed from repertoire.
Here is my code for when the the program is selected from the list box.
Public dtbConnecter As New OleDbConnection
Dim fileLocator As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source = " + Application.StartupPath + "\Musician Record Log.accdb"
Private Sub lstPro_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstPro.SelectedIndexChanged
Dim programID As String
Dim programIDLength As Integer
Dim selectedString As String = lstPro.GetItemText(lstPro.SelectedItem)
programIDLength = selectedString.IndexOf(":")
programID = selectedString.Substring(0, programIDLength)
MsgBox(programID)
Dim SQL As String = "Select Program.ProgramName, Program.ProgramLength, Repertoire.NameOfPiece, Repertoire.Composer From ((ProgramList INNER JOIN Repertoire ON ProgramList.PieceID = Repertoire.PieceID) INNER JOIN Program ON ProgramList.ProgramID = Program.ProgramID) WHERE (Program.ProgramID = #Param1)"
Dim da As New OleDbDataAdapter
Dim dtbTable As New DataTable
Dim ds As New DataSet
Dim dtbCommand As New OleDbCommand
dtbCommand.Parameters.Add("#Param1", OleDbType.VarChar).Value = programID
dtbCommand.Connection = dtbConnecter
dtbCommand.CommandType = CommandType.Text
dtbCommand.CommandText = SQL
da.SelectCommand = dtbCommand
da.Fill(dtbTable)
'Here i would then use the table's information to update my form, however first i'm trying to get this to work.
da.Dispose()
da = Nothing
End Sub
I also import System.Data, System.Data.OleDb and System.Drawing.Imaging at the top.
It was just a stupid mistake, the names of the fields in the database are NameOfProgram and LengthOfProgram but in the SQL query I used ProgramName and ProgramLength, thanks for all the help in ensuring the SQL query was correct and I did need to correct the data type but the main problem was the wrong identifier.

VB.NET SQLClient Table Names are ambiguous

Here is some simple sample code that demonstrates how I am getting results back from SQL Server:
Dim dtbTable As System.Data.DataTable
Dim sdaDataAdapter As New System.Data.SqlClient.SqlDataAdapter()
sdaDataAdapter = New System.Data.SqlClient.SqlDataAdapter("SELECT * FROM A; SELECT * FROM B", Connection)
dtbTable = New System.Data.DataTable()
dtbTable.Locale = System.Globalization.CultureInfo.InvariantCulture
sdaDataAdapter.Fill(dtbTable)
sdaDataAdapter = Nothing
objCommandBuilder = Nothing
In .Net, table A will come out TABLE and Table B will come out TABLE1... I want them to hold their real table names.
How do I get the real table names of the tables that come in from the SQL Query ? All the column names are correct, but the tables come out TABLE, TABLE1, TABLE2... I obviously know how to set them in my code or parse the table names and set them in code... I am wondering why .Net looses the table names in the first place and if there is a way for them to not be turned into ambiguous names.
Why would the writers of the SQLClient drivers not think we care about table names?
Any ideas from anyone on a way to get around this without having to set Table Name manually?
Here are two approaches - map the tables to DataTables and load the DataSet one table at a time w/desired name.
Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click
Dim Connection As New SqlConnection(OISConnectString)
Connection.Open()
Dim da As New System.Data.SqlClient.SqlDataAdapter("SELECT * FROM FIS..FIS_Log; SELECT * FROM FIS..FIS_Log_CA", Connection)
Dim ds As New DataSet
da.Fill(ds)
Debug.Print(ds.Tables(0).TableName) ' Table
Debug.Print(ds.Tables(1).TableName) ' Table1
Dim dtLog As DataTable = ds.Tables(0)
Dim dtLog_CA As DataTable = ds.Tables(1)
' work with DataTables by name
Stop
'reset
ds = Nothing
da = Nothing
ds = New DataSet()
da = New SqlDataAdapter("SELECT * FROM FIS..FIS_Log", Connection)
da.Fill(ds, "FIS_Log")
da = New SqlDataAdapter("SELECT * FROM FIS..FIS_Log_CA", Connection)
da.Fill(ds, "FIS_Log_CA")
Debug.Print(ds.Tables(0).TableName) ' Table
Debug.Print(ds.Tables(1).TableName) ' Table1
dtLog = ds.Tables("FIS_Log")
dtLog_CA = ds.Tables("FIS_Log")
Connection.Close()
End Sub
You might find TableAdapterManager useful depending on your platforms

OLEDB - select Count not working

Find below what I've done so far, but unfortunately it's not working.
Private BS as New BindingSource
Dim ds As New DataSet
' Make the Connection
Using con As New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source = Database1.mdb")
con.Open()
Dim Sql = "SELECT COUNT ([Eventname]) FROM Eventproposal"
Dim da = New OleDb.OleDbDataAdapter(Sql, con)
da.Fill(ds, "Eventproposal")
' Set the Binding Source
bs.DataSource = ds.Tables("Eventproposal")
con.Close()
End Using
TextBox1.DataBindings.Add("Text", bs, "")
Couple things, you should end all SQL Commands to MS Access with ;
Dim Sql = "SELECT COUNT ([Eventname]) FROM Eventproposal;"
And you did not name your column which will give you an error when you attempt to access it by name.
Dim Sql = "SELECT COUNT ([Eventname]) AS Eventname FROM Eventproposal;"
I believe it will give it a name but not what your thinking. Lastly, when you do your binding, you will have to reference the name of the field in the table.
TextBox1.DataBindings.Add("Text", bs, "Eventname")