Adding duplicate rows of data to my access database - asp.net

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.

Related

Evaluating whether a page is the result of a referral from a particular page

I have an Edit Profile page which allows users to change their information - currently it only allows users who have a record in the table 'userprofiles' to edit their information. I want newly registered users to be able to edit their profiles as well.
At the minute, I am using the ASP.NET membership system with the appropriate asp.net_ tables in an Access database to store user credentials. The 'userprofiles' table is a separate table which has more personal information in it. There is no link between the two tables
Here is my code behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsCrossPagePostBack Then
SeparateNewUserFunction()
Return
End If
If Not IsPostBack Then
DisplayData()
SaveConfirmation.Visible = False
End If
End Sub
And here is my DisplayData() function just if anyone was interested as to what it does:
Protected Sub DisplayData()
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
Dim newEmailAddress = ""
Dim newDescription = ""
If Not IsDBNull(profileDr("EmailAddress")) Then newEmailAddress = profileDr.Item("EmailAddress")
If Not IsDBNull(profileDr("Description")) Then newDescription = profileDr.Item("Description")
If Not IsDBNull(profileDr("AvatarURL")) Then ProfilePic.ImageUrl = profileDr.Item("AvatarURL")
description.Text = newDescription
email.Text = newEmailAddress
conn.Close()
End Sub
Rather than checking if a record exists in the 'userprofiles' table that matches the User.Identity.Name of the current user, I thought it would be easier just to evaluate whether or not the user had just been redirected from the Register.aspx page. (If this evaluation is true, then as you can see above, a separate "New User" function will be called).
That is my logic, but I have no clue if VB.NET has a "referrer" or "isReferred" expression? (at the minute as you can see I thought isCrossPagePostback might be the right thing but no luck!)
Any ideas?
You need to check whether or not a record exists and base your logic on that. That is the only right way to do it. As in:
What if you introduce a new page to handle registrations? This logic breaks.
What if you one day you retire and the next guy decides to rename the Register.aspx page? This logic breaks.
What if user hits back button and clicks the Register button again? This logic may break.
You should also consider a foreign key and unique constraint on that table, as well as using UserId instead of TravellerName. TravellerName can change, UserId will not.
... and yes you can the referring page by using HttpRequest.ServerVariables, which gets you a list of IIS Server Variables.

How can I make the logged-In name the default option in dropdownlist box?

Experts.
When a user logs into one of our web apps, there is a dropdownlist containing the names of all of our employees.
An employee could log into the system to record his or her entries into the database.
The employee could log the entries for another employee.
So far, an employee has had to select his or her name from the dropdown list and we don't want employees typing their names, just for consistency and to preserve data integrity.
Our problem currently is how to have employee's login name become the default option in the dropdown. The employee can select another name from the list if making the entries for another empployee.
Any ideas how to accomplish this task?
Thanks alot in advance.
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
Dim s As String
Dim reader As OleDbDataReader
txtFullName.Text = Session.Item("assignedTo").ToString
'Initialize Connection
s = "Select login_id, UserName from tblusers ORDER BY UserName"
Dim connStr As String = ConfigurationManager.ConnectionStrings("allstringconstrng").ConnectionString
Dim conn As New OleDbConnection(connStr)
Dim cmd As New OleDbCommand(s, conn)
'Open the connection
conn.Open()
Try
'Execute the Login command
reader = cmd.ExecuteReader()
'Populate the list of Users
txtLoginName.DataSource = reader
txtLoginName.DataValueField = "login_id"
txtLoginName.DataTextField = "UserName"
txtLoginName.DataBind()
'Close the reader
reader.Close()
Finally
'Close Connection
conn.Close()
End Try
End If
End Sub
<--new code -->
Try
'Execute the Login command
reader = cmd.ExecuteReader()
'Populate the list of Users
Dim currentUserName As String = ""
While reader.Read()
If (reader("login_id").ToString().Equals(currentUserName)) Then
currentUserName = reader("UserName").ToString()
End If
End While
txtLoginName.SelectedValue = currentUserName
'Close the reader
reader.Close()
Finally
'Close Connection
conn.Close()
End Try
you can use Page.User property to get the Name and then assign it to the dropdown's selected Value on Page_Load event.
Could you just simply select it by text after you populate the list? I assume you'll know the login_id once the user logs in, so you could find the username from the results of the query, like so:
UNTESTED:
string currentUserName = "";
While reader.Read()
If (reader("login_id").ToString().Equals(currentUserLogin)) Then
currentUserName = reader("UserName").ToString()
End If
End While
And then, once the list is populated via the results, select the correct user by username.
txtLoginName.Items.FindByValue(UserName).Selected = true;
Or even better yet, since you should already know the login_id, you can simply select by value from the populated drop down list, like so:
txtLoginName.SelectedValue = login_id
It's worth noting that this is making a very big assumption that the login_id will exist in the list. You may want to perform the appropriate check first to see if the login_id exists before selecting.
If you are using forms or windows authentication, wouldn't you just use:
txtLoginName.Text = User.Identity.Name
I believe this will select it if the text is in the list and matches exactly. Or, just use Sam's method. But was it the User.Identity.Name that you were looking for?

Populating dropboxes with SQL data

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!

Identity of recently added record and insert from gridview?

I am developing an ASP.Net VB Web Application
The application contains a GridView which displays the records of a user table from my created datable. The database is an Sql server database.
The code below inserts data into one table and through the built in function ##Identity to insert the most recently added record id (tt_id) from the trainingTbl table and inserting that record id into the userAssessmentTbl. Adding the identity to the second userAssessmentTbl table works fine.
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lblUsr2 As Control = FindControlRecursive(MultiTabs, "txtUsr")
Dim strQuery As String
Dim cmd As SqlCommand
strQuery = "Insert into trainingTbl(s_id, t_date, EditorId, wa_id, st_id) values(#s_id , #t_date, #EditorId, #wa_id, #st_id ) Insert into userAssessmentTbl(tt_id, UserId) values(##Identity, #UserId)"
cmd = New SqlCommand(strQuery)
cmd.Parameters.AddWithValue("#s_id", DDLCourse.Text)
cmd.Parameters.AddWithValue("#t_date", Convert.ToDateTime(txtDate.Text))
cmd.Parameters.AddWithValue("#EditorId", User.Identity.Name.ToString())
cmd.Parameters.AddWithValue("#st_id", myLblStation.Value().ToString)
cmd.Parameters.AddWithValue("#wa_id", myLblWatch.Value().ToString)
cmd.Parameters.AddWithValue("#UserId", lblUsr2.UniqueID.ToString)
InsertUpdateData(cmd)
End Sub
The issue I’m having seems to be centered on how I insert a uniqueidenifier from a GridView into a userAssessmentTbl database!
And how, I guess using a loop I can insert the UserId records from that Gridview (GridView1) into the userAssessmentTbl table along with the looped id from the ##Identity.
This part of the insert parameter seems to be incorrect:
cmd.Parameters.AddWithValue("#UserId", lblUsr2.UniqueID().ToString)
And the error I’m met with is: 'Conversion failed when converting from a character string to uniqueidentifier.'
I’ve also tried it like this:
cmd.Parameters.AddWithValue("#UserId", SqlDbType.UniqueIdentifier).Value().ToString()
And im met with the error: 'Operand type clash: int is incompatible with uniqueidentifier'
The qusetion has slightly changed to how do I Insert a String into SQL DB Where DataType Is Uniqueidentifier?
Any help will be really appreciated.
Well first of all:
##IDENTITY returns the most recently created identity for your current
connection, not necessarily the identity for the recently added row in
a table. Always use SCOPE_IDENTITY() to return the identity of the
recently added row.
Secondly, to asnwer your question:
The SQL type Uniqueidentifier and the CLR type Guid match up.
So instead of passing "#UserId" in as a parameter you need to create a Guid out of the string value.
Dim userID As Guid = New Guid(lblUsr2.UniqueID.ToString)

asp.net (web forms with VB.Net) connecting to a sql database

I'm trying to write a method in VB.net so that when I click a button it queries the database and returns all the values which match a textbox which is located next to the button. I have no idea how to do this, I assume in the onclick method for the button I will need to pull in the value from the textbox, connect to the database and display the results to a gridview?
Any help is greatly appreciated.
thanks :)
Marc
The two "best" options are to either use a Table Adapter or Entity Framework.
http://msdn.microsoft.com/en-us/library/bz9tthwx(v=vs.80).aspx (Table Adapter)
http://msdn.microsoft.com/en-us/library/bb399567.aspx (Entity Framework)
Both options will give you a GUI interface to build the connection and back end database queries. Entity Framework is the newer technology of the two. Table Adapters are probably easier to learn/understand if your unsure. (Que "easy" comments now)
I would give code examples but you'll have to understand some basics of either for them to make any sense. The basic examples in either link should be enough for what you need.
Both options will give you the ability to databind your datagrid to the results.
DISCLAIMER: This code is prone to SQL injection attacks and should not be used in a production environment. For testing only. Specifically:
strSQL = "SELECT * from Table where charindex ('" & TextBox1.Text & "', columnname) > 0 "
First in the web.config add this section that points to your database:
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
For the example, I've just used the standard database which is attached when you start a new vb.net web application in VisualStudio 2010.
Then in your Default.aspx, have something like this:
<asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
<asp:Button runat="server" Text="Button" ID="Button1" />
And in the code behind you could do something like this:
Imports System.Data.SqlClient
Public Class _Default
Inherits System.Web.UI.Page
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim strSQL As String = String.Empty
' Define your select statement
strSQL = "SELECT * from Table where charindex ('" & TextBox1.Text & "', columnname) > 0 "
' Fire up SQLConnection with a DataReader
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString)
Dim command As New SqlCommand(strSQL, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
While reader.Read()
Try
' Do some magic with reader.GetValue()
Catch ex As Exception
End Try
End While
reader.Close()
connection.Close()
End Using
End Sub
End Class
Ofcourse you'd have to validate the textbox.text before placing it directly into the select statement, but this will do the trick.
The 'CharIndex' will loop through the column specified as the second parameter and check if there's a match between the column data and the textbox.text, if so it will return the row.
The reader will loop through the results and with the reader.GetValue you can retrieve the data and do your magic.
Instead of using a SQLDataReader you can of course attach it to a Databound Grid or something else...

Resources