Populating dropboxes with SQL data - asp.net

I have a few more questions regarding my latest project. Ive felt like I have made some pretty good strides over the last couple days, but I am still struggling on a few of the core concepts of the SQL libraries, namely reading from specific columns and deleting entire rows.
Over the last week I was able to build a webform, save excel files to the server, open those files and export data into specific SQL tables, and bind the data to specific data grids depending on what the user chooses through a dropdown.
What I would like to accomplish is: Dynamic population of another dropdown depending on what the user chooses from the first drop down. More specifically, I have 4 tables, in the first column of each table I have serial numbers, if the user chooses Table2 in the first drop down, I would like the second dropdown to display all the serial numbers from column1 of Table2. Then if the user choose a specific serial number from the second drown down it populates a datagrid with columns 1-5 of that related row.
The second part is to create a delete button that the user can push after the information is displayed in the datagrid, that deletes the entire row of the serial number entry from that table.
This is what I have managed to Frankenstein together from other examples:
Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As System.EventArgs)
DropDownList2.Enabled = True 'its remains disabled until the user selects something from the first box
Using con As New SqlClient.SqlConnection
con.ConnectionString = "Data Source=.\SQLEXPRESS;AttachDbFilename=" & AppPath & "App_Data\DeviceDatabase.MDF;Integrated Security=True;User Instance=True;"
Using cmd As New SqlClient.SqlCommand
cmd.Connection = con
End Using
Dim cmdSQL As New SqlCommand()
cmdSQL.CommandType = Data.CommandType.Text
cmdSQL.CommandText = "SELECT Fieldname1 FROM " & """" & DropDownList1.SelectedItem.ToString & """" 'Im pretty sure this isnt right, and the reason I use """"" is because some of the items in the dropdown have spaced words.
Dim adptSQL As New SqlClient.SqlDataAdapter(cmdSQL)
Dim myDataSet As New DataSet()
adptSQL.Fill(myDataSet)
With myDataSet.Tables(DropDownList1.SelectedIndex) 'I think this is right
For rowNumber As Integer = 0 To .Rows.Count - 1
With .Rows(rowNumber)
DropDownList2.Items.Add(col1.rowNumber) 'This is obviously not working
End With
Next
End With
End Using
End Sub
Then, Im not quite sure how to populate the data table with the row that was selected, though currently I am able to do the entire table with using:
Private Sub GenTables(ByVal DropList As Object)
If DropList.SelectedIndex = 0 Then
GridView1.DataSourceID = Nothing
ElseIf DropList.SelectedIndex = 1 Then
GridView1.DataSourceID = "SqlDataSource1"
ElseIf DropList.SelectedIndex = 2 Then
GridView1.DataSourceID = "SqlDataSource2"
ElseIf DropList.SelectedIndex = 3 Then
GridView1.DataSourceID = "SqlDataSource3"
ElseIf DropList.SelectedIndex = 4 Then
GridView1.DataSourceID = "SqlDataSource4"
End If
GridView1.DataBind()
End Sub
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:DeviceDatabaseConnectionString1 %>"
ProviderName="<%$ ConnectionStrings:DeviceDatabaseConnectionString1.ProviderName %>"
SelectCommand="SELECT [Device:] AS column1, [SWversion:] AS column2, [Date:] AS column3, [Tester:] AS column4, [Wifi Preferred InCov:] AS column5 FROM [Galaxy Nexus]">
</asp:SqlDataSource>
'there are 3 more of these.
But I have these tables "hard coded" into the application, I can't obviously do this with every single table row. So how do I populate a datagrid without setting a SQLDataSource ahead of time in asp?
And lastly deleting the row that relates to the information displayed in the datagrid on the click of a button. If if can get a little help with the first part, Im sure I can figure out the second part.
So pretty much what I am asking is: how to populate a drop down with all the items from Coloumn1? and how to populate a datagrid from a specific row?
Any and all help is always greatly appreciated. Thanks Guys
Zach
EDIT
hmm I think I was making this a ton harder then it had to be, right now I am working with this:
Protected Sub BindDrop_Click(sender As Object, e As System.EventArgs)
DropDownList2.DataSourceID = "SqlDataSource5"
DropDownList2.DataBind()
End Sub
<asp:SqlDataSource ID="SqlDataSource5" runat="server"
ConnectionString="<%$ ConnectionStrings:DeviceDatabaseConnectionString1 %>"
ProviderName="<%$ ConnectionStrings:DeviceDatabaseConnectionString1.ProviderName %>"
SelectCommand="SELECT [Device:] AS column1 FROM [Galaxy Nexus]">
Its not quite right but its closer and in 1/10th the lines

alright guys i figured it out, I needed to use the ExecuteReader function (which crazily enough I couldnt find one article in auto population that uses this method). Hopefully in writing/answering this I make someone's life much easier.
Protected Sub DropDownList2_SelectedIndexChanged(sender As Object, e As System.EventArgs)
DropDownList3.Enabled = True
DropDownList3.Items.Clear()
Dim newsqlcommand As String = "Select [SWversion:] FROM " & """" & DropDownList2.SelectedItem.ToString & """"
Using con As New System.Data.SqlClient.SqlConnection(connexstring)
con.Open()
Using cmd As New SqlCommand(newsqlcommand, con)
Dim myReader As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While myReader.Read()
DropDownList3.Items.Add(myReader.GetString(0))
End While
myReader.Close()
cmd.Dispose()
End Using
con.Close()
con.Dispose()
End Using
Dbind()
End Sub
This successfully reads all the items in the column "SWVersion" and adds them to the dropdown in dropdown3. Enjoy!

Related

ASP.NET - parametrize query for SqlDataSource in ASP.NET code behing- VB.NET / Visual Studio 2010

I am creating a query for a SqlDataSource in ASP.NET from code behind.
My code is as following:
Dim SqlDataSource1 As New SqlDataSource()
Dim SQL As String
' If Not IsPostBack Then
SqlDataSource1.ID = "sqlexpsearch"
Me.Page.Controls.Add(SqlDataSource1)
Dim connectionString As String
Dim connection As SqlConnection
connectionString = ConfigurationManager.ConnectionStrings("exam2ndconnection").ToString
connection = New SqlConnection(connectionString)
SqlDataSource1.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("exam2ndconnection").ConnectionString
If opname.Checked = True Then
SQL = "select SRNO,tr_date as Date ,MailMethod,SpeedId,Content,ExYear,Exroll as No,NAME,Address from dispatch where name = '%'+ #srname +'%' OR ADDRESS ='%'+ #srname +'%' order by TR_DAte DESC,NAME "
SqlDataSource1.SelectParameters.Add("#srname", UCase(txtitem.Text))
SqlDataSource1.SelectCommand = SQL
End If
If opchno.Checked Then
SqlDataSource1.SelectCommand = "select SRNO,tr_date as Date ,MailMethod,SpeedId,Content,ExYear,Exroll as No,NAME,Address from dispatch where rtrim(exroll) ='" & txtitem.Text & "' order by tr_Date,exroll desc"
End If
GridView1.DataSource = SqlDataSource1
GridView1.DataBind()
I get this error:
Must declare the scalar variable "#srname".
on the line of code:
Gridview1.DataBind()
Please help to resolve this problem.
I would avoid trying to inject (add) a sql datasource into a page. (they don't persist anyway - you would have to re-inject each time).
However, DO keep in mind that any data aware control ALWAYS will automatic persist for you anyway.
The above information is thus great, since then you don't even have to bother with the sql data source. This is especially so in your example - you want to fill out a dropdown list, a grid view - whatever. In those cases? Just shove into that control a datatable - and your off to the races.
As noted, a lot of us use + prefer using code in place of a data source on the page - I find them rather messy and a pain to work with anyway.
In fact, what I will often do is say drop in a listbox, or even a grid view. I then use the wizard to create new data source - lay out the grid real nice and fast. I then go into the markup, remove the data source conrol that appears in the page.
Also, don't forget to remove the DataSourceID = from the Gridview markup (or whatever control you using).
This lets me still use the wizards to create the gridview, listview etc. but then I delete that extra junk, and wind up with a nice clean page without all that extra stuff in the page - (which is a pain to control from code anyway).
So, say for your example?
Try coding it this way:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(ConnectionStrings("exam2ndconnection").ConnectionString)
Dim strSQL As String = ""
strSQL = "SELECT SRNO, tr_date as Date, MailMethod, SpeedId, Content, ExYear, Exroll as No, " &
"[Name], Address FROM dispatch "
Dim strWhere As String = ""
Using cmdSQL As New SqlCommand(strSQL, conn)
If opName.Checked Then
strWhere = "([Name] Like '%'+ #srname +'%' OR ADDRESS = '%'+ #srname +'%') "
cmdSQL.Parameters.Add("#srname", SqlDbType.NVarChar).Value = txtitem.Text
End If
If opchno.Checked Then
If strWhere <> "" Then strWhere &= " AND "
strWhere &= "(Rtrim(exroll) = #exroll)"
cmdSQL.Parameters.Add("#exroll", SqlDbType.NVarChar).Value = txtitem.Text
End If
If strWhere <> "" Then
cmdSQL.CommandText &= " WHERE " & strWhere
End If
' add our sorting
cmdSQL.CommandText &= " ORDER BY tr_Date, exroll DESC"
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
A few things:
YES DO NOT forget to put the load of such data inside of the PostBack = false.
Load the results into a datatable (there are several reasons for this, but one BIG reason is that the row data bound event will have full use of that data row - including the WHOLE data row - even columns that are NOT part of the gridview.
note careful in above.
If you don't check "opname", then the criteria is not added.
if you don't check "opchno", then the criteria is not added.
if you check either one - the criteria for that option is added
so, if you check none, no criteria
if you check both, then you get both filters. So this allows you add even more options, and they are ALL optional - and we "clumative" can build up selection criteria this way.

VB.NET Connection string ADODB Connection (Web.Config)

I write the code below to connect database using web config but cannot connect database using ADODB to fetch data from database into textboxes
Webconfig
<connectionStrings>
<clear />
<add name="constr" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|CustomerInfor.mdb" providerName="System.Data.OleDb"/>
</connectionStrings>
SearchButton
Dim consString As String = System.Configuration.ConfigurationManager.ConnectionStrings("constr").ConnectionString
Dim objConn As New OleDbConnection(consString)
objConn.Open()
Please help with right code to fetch data from database into textboxes
Thanks
Ok, lets try this a bit different.
First up: Lets get the connection string OUT side of the code.
Like for desktop, or anything else? You can add values like connection string to the project like this:
And really nice is you get to use the connection builder to do this.
The above setting are shoved into web.config for you automatic.
So, setup your connection in above.
Ok, now in this case, I just shove on the screen a few text boxes for a user and hotel name.
Real plane jane like this:
<div style="width:25%;text-align:right;padding:25px;border:solid;border-width:1px">
<style> .tbox {width:260px;margin-left:5px;margin-bottom:15px;border-radius:8px;border-width:1px}</style>
Hotel Name: <asp:TextBox ID="txtHotelName" runat="server" class="tbox"/>
<br />
First Name: <asp:TextBox ID="txtFirst" runat="server" class="tbox" />
<br />
Last Name:<asp:TextBox ID="txtLast" runat="server" class="tbox"/>
<br />
City: <asp:TextBox ID="txtCity" runat="server" class="tbox"/>
<br />
Active:<asp:CheckBox ID="ckActive" runat="server" />
<br />
<br />
Ok, now our code to load this. I don't have a text box or source for the id, but a integer value OR a text value will work.
So, our code to load up is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData()
End If
End Sub
Sub LoadData()
Dim cmdSQL As OleDbCommand = New OleDbCommand()
cmdSQL.CommandText = "SELECT * from tblhotels where ID = #ID"
cmdSQL.Parameters.Add("#ID", OleDbType.Integer).Value = 23
Dim rst As DataTable = MyRst(cmdSQL)
With rst.Rows(0)
txtHotelName.Text = .Item("HotelName")
txtFirst.Text = .Item("FirstName")
txtLast.Text = .Item("LastName")
txtCity.Text = .Item("City")
ckActive.Checked = .Item("Active")
End With
ViewState("rst") = rst
End Sub
Note the cute helper routine MyRst.
So, you can use that routine EVERY where. eg:
Dim cmdSQL As OleDbCommand = New OleDbCommand("select * from RoomTypes")
Dim rst as DataTable = MyRst(cmdSQL)
So, it just a handy dandy routine. (you do NOT have to use parameters if you don't need them).
Ok, so we loaded the one row into the table (and we save that row for later use into ViewState)
Ok, so now we see this:
Now, the save code. Note how we used a record set (datatable) in place of a GAZILLION parameters.
We do this for quite a few reasons.
Strong data type conversion occurs here.
Parameter order for the save does not matter. I can cut-paste, or add 5 or 15 more columns here, and it works - and order does not matter!!!
So, now the save code.
Protected Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
SaveData()
End Sub
Sub SaveData()
Dim rst As DataTable = ViewState("rst")
Using con As New OleDbConnection(My.Settings.AccessTest2)
Using cmdSQL As New OleDbCommand("SELECT * from tblHotels WHERE ID = 0", con)
Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmdSQL)
Dim daSQLU As OleDbCommandBuilder = New OleDbCommandBuilder(da)
con.Open()
With rst.Rows(0)
.Item("HotelName") = txtHotelName.Text
.Item("FirstName") = txtFirst.Text
.Item("LastName") = txtLast.Text
.Item("City") = txtCity.Text
.Item("Active") = ckActive.Checked
End With
da.Update(rst)
End Using
End Using
End Sub
NOTE: not a bug, I MOST certainly did use where ID = 0
So, the nice part is we can add more text box etc. We will have to add code to setup the text boxes, but at least the order don't matter.
Last but not least?
That helper routine, the one I use to fill datatables. I even use it for say filling out combo box (dropdown lists), or whatever.
Public Function MyRst(cmdSQL As OleDbCommand) As DataTable
Dim rstData As New DataTable
Using MyCon As New OleDbConnection(My.Settings.AccessTest2)
cmdSQL.Connection = MyCon
MyCon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
Return rstData
End Function
So note how we used the connection string setting that we setup in the project.
And since access is sensitive to parameter order, then I adopted the above idea of using a data table. Note that this approach also works for a grid, or even adding rows. When you run that update routine? rows added, rows edits, row deleted?
They all are done for you with the ONE da.Upate(rst).
Note also, you should set your project to run as x86, and not x64, since JET ONLY can work as x32. However, the ACE data engine can be had for x64 bits.

how to position column names vertically in datagridview in vb.net

I appologise in advance if my question may appear silly to you but I have a problem with positioning column names in a dataGridview vertically. I'm populating DataGridView using flowing code:
Dim StrQwery As String = "SELECT * FROM employees WHERE employee_id = (select MAX(employee_id) FROM employees AND registered = 'UNREGISTERED';
Dim smd As MySqlCommand
smd = New MySqlCommand(StrQwery, myconn)
smd.CommandType = CommandType.Text
Dim da As New MySqlDataAdapter(smd)
Dim cb As New MySqlCommandBuilder(da)
Dim ds As New DataSet()
da.Fill(ds)
GridView1.DataSource = ds.Tables(0)
If n = 1 Then
If Not Page.IsPostBack Then
GridView1.DataBind()
End If
Else
GridView1.DataBind()
End If
everything works perfectly except that I need to position account attributes like name, position, ID number etc not horizontally but vertically. Something like this:
|NAME | John |
|SURNAME | Philips|
|POSITION| Manager|
and I can't find a way how to do it. Can anyone give me a hint in my problem please?
many thanks in advance.
If you want to present a detailed view of DB record, GridView is not the best choice (which is more suitable for tabular display of multiple records).
For your case take a look at DetailsView control

Adding duplicate rows of data to my access database

Hey there Im having difficulties adding a single row of data to my database when I submit my form it insert two rows of data to my mdb database any suggestions samples or help will work ill really appreciate it Thanks
Protected Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim conCoaxis As OleDbConnection
Dim strInsert As String
Dim cmdInsert As OleDbCommand
conCoaxis = New OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\site\App_Data\sabersolutions.mdb")
strInsert = "INSERT INTO register (Name, Email, Newsletter) Values (?, ?, ?)"
cmdInsert = New OleDbCommand(strInsert, conCoaxis)
cmdInsert.Parameters.Add("#Name", OleDbType.VarWChar, 255).Value = txtName.Text
cmdInsert.Parameters.Add("#Email", OleDbType.VarWChar, 255).Value = txtEmail.Text
cmdInsert.Parameters.Add("#Newsletter", OleDbType.Boolean, 1).Value = ckNews.Checked
Try
conCoaxis.Open()
cmdInsert.ExecuteNonQuery()
conCoaxis.Close()
Response.Write("Updated Successfully!<p> </p><p> </p><p> </p>")
Catch
conCoaxis.Close()
End Try
Your code looks fine. It looks to me more like you have the sub-routine Button3_Click assigned as the handler more than once. For example in the aspx page you have something like
<asp:Button runat="server" ID="Button3" Text="Submit" OnClick="Button3_Click" />
See the OnClick attribute? that wires the click event to call Button3_Click
Then somewhere else, possibly in Page_Load in the .vb code-behind, you also have:
AddHandler Button3.Click, AddressOf Me.Button3_Click
So ONE click event will end up calling the same function twice. Get rid of the AddHandler code you don't need to manually wire-up click handlers, it's done for you.
If that's not your problem you may of course be clicking your button twice, this is a well known issue with HTML forms. You can Google many solutions. My preferred solution is to always do a 'SELECT' first to check if the record already exists, or wrap your insert command in a 'IF NOT EXISTS' (I think this works for MS Access, I know it dows for MS Sql Server)
strInsert = "IF NOT EXISTS (SELECT 1 FROM register WHERE Name = #Name AND Email = #Email AND Newsletter = #Newsletter) BEGIN INSERT INTO register (Name, Email, Newsletter) Values ( #Name, #Email, #Newsletter) END"
Another option is:
strInsert = "INSERT INTO register (Name, Email, Newsletter) SELECT TOP 1 #Name, #Email, #Newsletter FROM register WHERE NOT EXISTS (SELECT 1 FROM register WHERE Name = #Name AND Email = #Email AND Newsletter = #Newsletter)"
This latter statement only works if 'register' has at least one record in it, MS Access Jet database requires a table name in the statement, see here for more info. Seriously though, drop Access and use a proper database like SQL Server, then you can use the first statement directly or via a stored procedure a much more professional solution.

Reducing SQL connections to just 1 - ASP.net VB

I am currently working on an asp.net web page with a GridView displaying a table from a database. This GridView has 4 DropDownLists that will be used to filter the data shown on the GridView. When the page loads 4 Sub routines are run, each one connecting to the database with a select statement to fill the DropDownList with relevant filter headings.
Initially, I had one connection with a loop that populated all of the drop downs but these contained duplicates. I then split the filling of each DDL so that the select statements could contain DISTINCT.
I would like (and am sure there is a way here) to be able to populate all of the DDLs with data from one connection.
Code for one connection:
Protected Sub FillDepDDL()
Dim conn As New SqlConnection()
conn.ConnectionString = WebConfigurationManager.ConnectionStrings("TestDBConnectionString").ConnectionString
Dim connection As New SqlConnection(conn.ConnectionString)
connection.Open()
Const FillAllQS As String = "SELECT DISTINCT [Department] FROM [Employees]"
Dim command As New SqlCommand(FillAllQS, connection)
Dim reader As SqlDataReader = command.ExecuteReader()
Dim sel As New ListItem
sel.Text = "Please Select"
sel.Value = "*"
DDLDepartment.Items.Add(sel)
While reader.Read
Dim Deplist As New ListItem()
Deplist.Value = reader("Department")
Deplist.Text = reader("Department")
DDLDepartment.Items.Add(Deplist)
End While
reader.Close()
conn.Close()
End Sub
The other 3 column names: FirstName > DDLFN, LastName > DDLLN, Wage > DDLWag.
This is only a test DB and the princibles learned here will be applied to a larger live project.
I'm sure some guru will be able to work this out easily but I just can't get my head round it even after hours of searching.
Thanks in advance.
I'm adding this in as answer because I cannot format it in a comment, but this doesn't answer the original question of how to write the sql to return all three distinct result sets. Instead, it answers how to rewrite the code you have above so that connections are properly disposed of in case of an exception.
Protected Sub FillDepDDL()
Dim Deplist As ListItem
Dim sel As New ListItem
sel.Text = "Please Select"
sel.Value = "*"
DDLDepartment.Items.Add(sel)
Using conn As New SqlConnection(WebConfigurationManager.ConnecitonString("TestDBConnectionString").ConnectionString)
Using cmd As New SqlCommand("SELECT DISTINCT [Department] FROM [Employees]", conn)
conn.Open()
Using reader = cmd.ExecuteReader()
While reader.Read
Deplist = New ListItem()
Deplist.Value = reader("Department")
Deplist.Text = reader("Department")
DDLDepartment.Items.Add(Deplist)
End While
End Using
End Using
End Using
End Sub
I don't see any reason for you to try to return all three results in a single query. That will just make your code unnecessarily complicated just to save a millisecond or two. Connection pooling handles the creation of connections on the database server for you, so opening a new connection in your code is very fast.

Resources